Skip to content
This repository was archived by the owner on Jan 9, 2023. It is now read-only.

Commit 29bd3b5

Browse files
committed
Merge branch '0.1.1'
2 parents a6a94d6 + 8ea9c1b commit 29bd3b5

17 files changed

+412
-116
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ __pycache__
33
currency data cache.json
44
/Logs
55
eventDefinitions.json
6-
config.json
7-
[!.]*.py.[!.]*.py
6+
/configs
7+
/config.json

Profiles/Factorio - Advanced Usage Example.json

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"filteredActions": [
99
{
1010
"condition": "[ALL]",
11-
"manipulator": "",
12-
"action": "[BESTNAME] subscribed themselves"
11+
"manipulator": "'themselves'",
12+
"action": "[ACTION_SubscriptionBy]"
1313
}
1414
]
1515
},
@@ -19,8 +19,8 @@
1919
"filteredActions": [
2020
{
2121
"condition": "[ALL]",
22-
"manipulator": "",
23-
"action": "[BESTNAME] was subscribed by [gifter_display_name]"
22+
"manipulator": "'[gifter_display_name]'",
23+
"action": "[ACTION_SubscriptionBy]"
2424
}
2525
]
2626
},
@@ -43,6 +43,11 @@
4343
"manipulator": "int([VALUE]/10)",
4444
"action": "/a_custom_command [CALCVALUE] '[BESTNAME]'"
4545
},
46+
{
47+
"condition": "[VALUE] >= 0",
48+
"manipulator": "int([VALUE]/10)",
49+
"action": "I run with any value, including when the >10 action runs"
50+
},
4651
{
4752
"condition": "[ALL]",
4853
"manipulator": "myValue = floor([VALUE])\ncalcValue = myValue * 2",
@@ -71,6 +76,13 @@
7176
]
7277
}
7378
],
79+
"actions": [
80+
{
81+
"name": "SubscriptionBy",
82+
"description": "prints who subscribed and by whom. CALCVALUE must be provided as a string as otherwise it will be run like code",
83+
"effect": "[BESTNAME] subscribed by [CALCVALUE]"
84+
}
85+
],
7486
"options": {
7587
"twitchMysterSubGiftMode": "donator"
7688
}

README.md

Lines changed: 20 additions & 20 deletions
Large diffs are not rendered by default.

Source/Config.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def __init__(self, state):
88
self._fileName = "config.json"
99
self._settings = {}
1010
if Os.path.isfile(self._fileName):
11-
with open(self._fileName, "r") as file:
11+
with open(self._fileName, "r", encoding='utf-8') as file:
1212
data = Json.load(file)
1313
file.closed
1414
self._settings = data
@@ -22,7 +22,6 @@ def _PopulateMissingConfigDefaults(self):
2222
"Currency ApiLayerAccessKey": "",
2323
"Streamlabs SocketApiToken": "",
2424
"Profile Default": "",
25-
"Factorio PlayerName": "",
2625
"Rcon Server Address": "",
2726
"Rcon Server Port": 25575,
2827
"Rcon Server Password": "",

Source/Currency.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def GetRates(self):
1717
if Os.path.isfile(self.cacheFileName):
1818
self.logging.DebugLog(
1919
"Trying to get currancy rates from cache file")
20-
with open(self.cacheFileName, "r") as file:
20+
with open(self.cacheFileName, "r", encoding='utf-8') as file:
2121
data = Json.load(file)
2222
file.closed
2323
cacheDateTime = Datetime.date.fromtimestamp(data["timestamp"])
@@ -52,7 +52,7 @@ def _SourceRateData(self):
5252
self.state.RecordActivity(
5353
self.state.translations.GetTranslation("Currency WebsiteDownloadFailed"))
5454
return False
55-
with open(self.cacheFileName, "w") as file:
55+
with open(self.cacheFileName, "w", encoding='utf-8') as file:
5656
file.write(Json.dumps(response))
5757
file.closed
5858
for name, rate in response["quotes"].items():

Source/Gui.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,14 @@ def OnTestEventPlatformChanged(self, *args):
175175
def OnTestEventTypeChanged(self, *args):
176176
amountEnabled = False
177177
quantityEnabled = False
178+
payloadCountEnabled = False
178179
if self.selectedTestEventType.get() != self.translations.GetTranslation("Gui SelectTestEventType"):
179180
amountEnabled = self.state.testEventUtils.GetAttribute(self.selectedTestEventPlatform.get(
180181
), self.selectedTestEventType.get(), "valueInput")
181182
quantityEnabled = self.state.testEventUtils.GetAttribute(self.selectedTestEventPlatform.get(
182183
), self.selectedTestEventType.get(), "quantityInput")
184+
payloadCountEnabled = self.state.testEventUtils.GetAttribute(self.selectedTestEventPlatform.get(
185+
), self.selectedTestEventType.get(), "payloadInput")
183186
if amountEnabled:
184187
self.testEventValueLabel.config(state=TK.NORMAL)
185188
self.testEventValueInput.config(state=TK.NORMAL)
@@ -192,6 +195,10 @@ def OnTestEventTypeChanged(self, *args):
192195
else:
193196
self.testEventQuantityLabel.config(state=TK.DISABLED)
194197
self.testEventQuantityInput.config(state=TK.DISABLED)
195-
self.testEventPayloadCountLabel.config(state=TK.NORMAL)
196-
self.testEventPayloadCountInput.config(state=TK.NORMAL)
198+
if payloadCountEnabled:
199+
self.testEventPayloadCountLabel.config(state=TK.NORMAL)
200+
self.testEventPayloadCountInput.config(state=TK.NORMAL)
201+
else:
202+
self.testEventPayloadCountLabel.config(state=TK.DISABLED)
203+
self.testEventPayloadCountInput.config(state=TK.DISABLED)
197204
self.testEventButton.config(state=TK.NORMAL)

Source/Logging.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def _TidyUpOldLogFiles(self, logFolder, currentDT, daysLogsToKeep, dateFormat):
3333
def Log(self, text):
3434
self.DebugLog(text)
3535
fileName = self.logFilePath
36-
with open(fileName, "a") as file:
36+
with open(fileName, "a", encoding='utf-8') as file:
3737
file.write(self.TimestampText(text) + "\n")
3838
file.closed
3939

@@ -45,7 +45,7 @@ def DebugLog(self, text):
4545
if not self.debugLogging:
4646
return
4747
fileName = self.debugLogFilePath
48-
with open(fileName, "a") as file:
48+
with open(fileName, "a", encoding='utf-8') as file:
4949
file.write(self.TimestampText(text) + "\n")
5050
file.closed
5151

Source/Profiles.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def __init__(self, state):
1313
Os.mkdir(self.profileFolder)
1414
else:
1515
for fileName in Os.listdir(self.profileFolder):
16-
with open(self.profileFolder + "/" + fileName, "r") as file:
16+
with open(self.profileFolder + "/" + fileName, "r", encoding='utf-8') as file:
1717
data = Json.load(file)
1818
file.closed
1919
self.profiles[data["name"]] = Profile(data, self)
@@ -43,18 +43,15 @@ def __init__(self, profileData, profiles):
4343
else:
4444
self.options = Options(self, {})
4545

46-
def GetActionTextForEvent(self, event):
46+
def GetActionTextsForEvent(self, event):
47+
results = []
4748
for reaction in self.reactionPriorities[1]:
4849
if reaction.handlerName == event.handlerName:
49-
result = reaction.GetActionTextForEvent(event)
50-
if result != None:
51-
return result
50+
results += reaction.GetActionTextsForEvent(event)
5251
for reaction in self.reactionPriorities[2]:
5352
if reaction.valueType == event.valueType:
54-
result = reaction.GetActionTextForEvent(event)
55-
if result != None:
56-
return result
57-
return None
53+
results += reaction.GetActionTextsForEvent(event)
54+
return results
5855

5956

6057
class Reaction:
@@ -86,14 +83,15 @@ def __init__(self, reactionData, profile):
8683
else:
8784
self.filterActionPriorities[1].append(filteredAction)
8885

89-
def GetActionTextForEvent(self, event):
86+
def GetActionTextsForEvent(self, event):
87+
results = []
9088
for filterAction in self.filterActionPriorities[1]:
9189
if filterAction.DoesEventTriggerAction(event):
92-
return filterAction.GetActionText(event)
90+
results.append(filterAction.GetActionText(event))
9391
for filterAction in self.filterActionPriorities[2]:
9492
if filterAction.DoesEventTriggerAction(event):
95-
return filterAction.GetActionText(event)
96-
return None
93+
results.append(filterAction.GetActionText(event))
94+
return results
9795

9896
def GetPrintHandlerType(self):
9997
if self.handlerName != "":

Source/Streamlabs Rcon Integration.py

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
from Rcon import Rcon
1010
from Translations import Translations
1111
from TestEvents import TestEventUtils
12+
import random as Random
13+
import time as Time
14+
import threading as Threading
1215

1316

1417
class State():
1518
def __init__(self):
16-
self.version = "0.1.0"
19+
self.version = "0.1.1"
1720
self.config = Config(self)
1821
self.logging = Logging(self)
1922
self.config.LogMissingSettings()
@@ -110,6 +113,11 @@ def RecordActivity(self, text):
110113

111114
def OnStreamlabsEventHandler(self, data):
112115
try:
116+
random = Random.Random()
117+
random.seed(Threading.get_ident())
118+
sleepTime = random.random()
119+
self.logging.DebugLog("Sleeping event for: " + str(sleepTime))
120+
Time.sleep(sleepTime)
113121
self.logging.DebugLog(
114122
"Streamlabs raw event data: " + str(data))
115123
events = StreamlabsEventUtils.GenerateEventPerPayload(self, data)
@@ -135,37 +143,39 @@ def OnStreamlabsEventHandler(self, data):
135143
self.logging.DebugLog(
136144
"Streamlabs processed event: " + str(event))
137145

138-
actionText = self.profiles.currentProfile.GetActionTextForEvent(
146+
actionTexts = self.profiles.currentProfile.GetActionTextsForEvent(
139147
event)
140-
if actionText == None:
148+
if len(actionTexts) == 0:
141149
self.RecordActivity(
142150
self.translations.GetTranslation("StreamlabsEvent NoProfileAction") + event.GetEventRawTitlesAsPrettyString())
143151
self.logging.DebugLog(
144152
"No profile action for: " + event.GetEventRawTitlesAsPrettyString())
145153
return
146-
actionType = ""
147-
response = ""
148-
if actionText == "":
149-
actionType = "Ignore event"
150-
self.logging.DebugLog(
151-
"NOTHING action specified for: " + event.GetEventRawTitlesAsPrettyString())
152-
else:
153-
actionType = "Rcon command"
154-
try:
154+
for actionText in actionTexts:
155+
actionType = ""
156+
response = ""
157+
if actionText == "":
158+
actionType = "Ignore event"
155159
self.logging.DebugLog(
156-
"Doing Rcon command: " + actionText)
157-
response = self.rcon.SendCommand(actionText)
158-
except Exception as ex:
159-
self.logging.RecordException(ex, "Rcon event failed")
160+
"NOTHING action specified for: " + event.GetEventRawTitlesAsPrettyString())
161+
else:
162+
actionType = "Rcon command"
163+
try:
164+
self.logging.DebugLog(
165+
"Doing Rcon command: " + actionText)
166+
response = self.rcon.SendCommand(actionText)
167+
except Exception as ex:
168+
self.logging.RecordException(
169+
ex, "Rcon event failed")
170+
self.RecordActivity(
171+
self.translations.GetTranslation("Rcon CommandError") + actionText)
172+
return
173+
if response != "":
160174
self.RecordActivity(
161-
self.translations.GetTranslation("Rcon CommandError") + actionText)
162-
return
175+
self.translations.GetTranslation("Rcon CommandResponseWarning") + response)
176+
self.logging.DebugLog("Action done: " + actionText)
163177
self.RecordActivity(
164178
self.translations.GetTranslation("StreamlabsEvent EventHandled") + event.GetEventRawTitlesAsPrettyString() + " : " + event.bestName + " : value " + str(event.value) + " : " + actionType)
165-
if response != "":
166-
self.RecordActivity(
167-
self.translations.GetTranslation("Rcon CommandResponseWarning") + response)
168-
self.logging.DebugLog("Action done: " + actionText)
169179
except Exception as ex:
170180
self.logging.RecordException(
171181
ex, "OBS Event Handler Critical Error - This event won't be processed")
@@ -194,15 +204,17 @@ def OnTestEventButtonHandler(self):
194204
self.RecordActivity(
195205
self.translations.GetTranslation("TestEvent QuantityCountNotInt") + str(testEventQuantity))
196206
return
197-
testEventPayloadCount = self.gui.testEventPayloadCount.get()
198-
try:
199-
testEventPayloadCount = int(testEventPayloadCount)
200-
if testEventPayloadCount <= 0:
201-
raise ValueError()
202-
except:
203-
self.RecordActivity(
204-
self.translations.GetTranslation("TestEvent PayloadCountNotInt") + str(testEventPayloadCount))
205-
return
207+
testEventPayloadCount = 1
208+
if TestEventUtils.GetAttribute(testEventPlatform, testEventType, "payloadInput"):
209+
try:
210+
testEventPayloadCount = self.gui.testEventPayloadCount.get()
211+
testEventPayloadCount = int(testEventPayloadCount)
212+
if testEventPayloadCount <= 0:
213+
raise ValueError()
214+
except:
215+
self.RecordActivity(
216+
self.translations.GetTranslation("TestEvent PayloadCountNotInt") + str(testEventPayloadCount))
217+
return
206218
testEventArray = self.testEventUtils.GenerateTestEventArray(
207219
testEventPlatform, testEventType, testEventValue, testEventQuantity, testEventPayloadCount)
208220
if len(testEventArray) > 0:
@@ -241,7 +253,7 @@ def Run(self):
241253
except:
242254
pass
243255
try:
244-
state.logging.RecordException(
256+
self.logging.RecordException(
245257
ex, "Application Critical Error - Application has been stopped")
246258
except:
247259
pass

Source/StreamlabsEvent.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ def __init__(self, state, platformString, typeString, payload):
2121
self.ignored = False
2222
self.rawMessage = payload
2323

24+
if "_id" in self.rawMessage:
25+
self.id = self.rawMessage["_id"]
26+
2427
if self.type == "donation" and self.platform == "":
2528
self.platform = "streamlabs"
2629
elif self.platform == "twitch_account" and self.type == "subscription" and "gifter" in self.rawMessage and self.rawMessage["gifter"] != None:
@@ -30,7 +33,6 @@ def __init__(self, state, platformString, typeString, payload):
3033
self.ignored = True
3134
return
3235

33-
self.id = self.rawMessage["_id"]
3436
if "display_name" in self.rawMessage.keys():
3537
self.bestName = self.rawMessage["display_name"]
3638
elif "name" in self.rawMessage.keys():
@@ -218,7 +220,7 @@ def FindAttributeTagsInString(string):
218220

219221
@staticmethod
220222
def LoadEventDefinitions():
221-
with open("eventDefinitions.json", "r") as file:
223+
with open("eventDefinitions.json", "r", encoding='utf-8') as file:
222224
data = Json.load(file)
223225
file.closed
224226
StreamlabsEventUtils.handledEventTypes = data
@@ -290,7 +292,12 @@ def GenerateEventPerPayload(state, data):
290292
typeString = data["type"]
291293
else:
292294
typeString = ""
293-
for payload in data["message"]:
295+
# twitch alerts only have a dictionary as message and not an array of dictionaries like all other scenarios
296+
if isinstance(data["message"], dict):
294297
events.append(StreamlabsEvent(
295-
state, platformString, typeString, payload))
298+
state, platformString, typeString, data["message"]))
299+
else:
300+
for payload in data["message"]:
301+
events.append(StreamlabsEvent(
302+
state, platformString, typeString, payload))
296303
return events

0 commit comments

Comments
 (0)