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

Commit f51f536

Browse files
committed
Merge branch 'v0.1.4'
2 parents 6af4945 + d73fef7 commit f51f536

11 files changed

+471
-26
lines changed

Build.bat

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@ECHO OFF
2-
set outputFolder=build\dist
3-
rd /s /q %outputFolder%
2+
set buildFolder=build
3+
set outputFolder=%buildFolder%\dist
4+
rd /s /q %buildFolder%
45
pyinstaller --onefile ".\Source\Streamlabs Rcon Integration.py" --workpath ".\build" --clean --distpath ".\build\dist" --specpath ".\build"
56
xcopy "Source\config.sample.json" "%outputFolder%" /q /y /i
67
xcopy "Source\eventDefinitions.json" "%outputFolder%" /q /y /i

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
A tool that allows you to do actions in games based on Streamlabs events. Current usage focuses around Twitch events via Streamlabs triggering actions within Factorio. The tool is written in Python for cross platform usage and runs fully on your pc to remove any risk of sharing access keys or donators details on the internet.
44

5-
The tool recieves events from Streamlabs and uses configurable logic to send RCON commands to the game server to do actions.
6-
The integration should support any game that allows for RCON and is coded to support multiple streaming platforms connected via Stramlabs; youtube, mixer and twitch.
5+
The tool receives events from Streamlabs and uses configurable logic to send RCON commands to the game server to do actions.
6+
The integration should support any game that allows for RCON and is coded to support multiple streaming platforms connected via Streamlabs; youtube, mixer and twitch.
77

88
This tool's setup is a little technical at present, but is fully functional and used by a few Factorio Twitch streamers. Any usage questions or issues grab me on discord: muppet9010#2645
99

@@ -20,7 +20,7 @@ Installation & Usage
2020
7. Run the program: Streamlabs Rcon Integration.exe
2121
8. Select the desired profile from the dropdown. Suggested are the `Print All` and `Print Most Fancy`.
2222
9. Click the Start button to connect the integration between Streamlabs and Factorio.
23-
10. The integration is now running between the Streamlabs account and the game using the selected profile. Test event sfrom streamlabs or from within the integration tool will now trigger activity within Factorio.
23+
10. The integration is now running between the Streamlabs account and the game using the selected profile. Test events from streamlabs or from within the integration tool will now trigger activity within Factorio.
2424

2525
Should a critical error occur the program may fail to load or close. Details can be found in the most recent log file within the Logs folder.
2626

@@ -36,7 +36,7 @@ The app takes in Streamlabs events and processes them through configurable profi
3636
Streamlab Events
3737
--------------
3838

39-
The complete list of Streamlabs events and their contained data attributes can be found in the [eventDefinitions.json file](https://github.com/muppet9010/Streamlabs-Rcon-Integration/blob/master/Source/eventDefinitions.json). The top section under `[ALL]` are generated and normalised by the program to provide some standard entries across all event types. The list of platform and event specific attributes are what Streamlabs is currently sending. These often vary from their platfrom documentation and change periodically, so please refer to this tools definition.
39+
The complete list of Streamlabs events and their contained data attributes can be found in the [eventDefinitions.json file](https://github.com/muppet9010/Streamlabs-Rcon-Integration/blob/master/Source/eventDefinitions.json). The top section under `[ALL]` are generated and normalised by the program to provide some standard entries across all event types. The list of platform and event specific attributes are what Streamlabs is currently sending. These often vary from their platform documentation and change periodically, so please refer to this tools definition.
4040

4141
Profile
4242
---------
@@ -48,14 +48,14 @@ Profiles are structured as the below:
4848
- Profile file (.json):
4949
- "name" - the name of the profile as seen within the application
5050
- "description" - a short description shown within the application for this profile
51-
- "reactions" - an array [] of unqiue reactions stored as dictionaries {} of attributes in key, value pairs.
51+
- "reactions" - an array [] of unique reactions stored as dictionaries {} of attributes in key, value pairs.
5252
- "platform" - the event platform identifier string for this reaction
5353
- "type" - the event type identifier string for this reaction
54-
- "filteredActions" - an array [] of unqiue filteredActions stored as dictionaries {} of attributes in key, value pairs.
54+
- "filteredActions" - an array [] of unique filteredActions stored as dictionaries {} of attributes in key, value pairs.
5555
- "condition" - a condition for this filteredAction being done as a string
5656
- "manipulator" - an optional value change script
5757
- "action" - the text string that will be sent via RCON after being processed, or the name of a profile "actions" to call.
58-
- "actions" - an array [] of unqiue actions stored as dictionaries {} of attributes in key, value pairs.
58+
- "actions" - an array [] of unique actions stored as dictionaries {} of attributes in key, value pairs.
5959
- "name" - the name of the action as called from filteredActions.
6060
- "description" - a description just used within the JSON for documentation purposes
6161
- "effect": - the text string that will be sent via RCON after being processed
@@ -66,7 +66,7 @@ Profiles are structured as the below:
6666
Event Handling via Profile
6767
==========
6868

69-
When a Streamlabs event is recieved by the app it reviews the reactions within the current profile to work out what actions to take.
69+
When a Streamlabs event is received by the app it reviews the reactions within the current profile to work out what actions to take.
7070

7171
Event Attributes
7272
-----------
@@ -87,13 +87,13 @@ Assuming a reaction for the event is found, the reaction's `filteredActions` are
8787
Filtered Actions
8888
--------------
8989

90-
Each `filteredActions` list will have one or more filteredAction entries in it. Each of these entries is reviewed and its action carried out if approperiate.
90+
Each `filteredActions` list will have one or more filteredAction entries in it. Each of these entries is reviewed and its action carried out if appropriate.
9191

9292
### Condition
9393

9494
The `condition` script in each filteredAction is evaluated and those that are met (resolves to True) will have their action executed for this event. All of the events data attributes from Streamlabs and this app can be used within the `condition` script in the format `[DATA_ITEM_NAME]`. i.e. `[VALUE] >= 5 and [VALUE] < 10`. The conditions within a reaction are order specific (excluding `[ALL]` condition) and can overlap each other's conditions if you wish both to be executed in those circumstances.
9595

96-
There is a special `[ALL]` conditon script value that will be triggered after all other suitable conditions have been triggered in all cases.
96+
There is a special `[ALL]` condition script value that will be triggered after all other suitable conditions have been triggered in all cases.
9797

9898
If a condition for a filtered action is met then the manipulator script and action are carried out
9999

@@ -112,26 +112,27 @@ Should an Rcon command get a response from the server it will be shown in the Ac
112112
Actions
113113
--------
114114

115-
The Actions list is a collection of named action command strings to enable their re-use when it's convenient. Their `effect` is identication to a filteredAction action.
115+
The Actions list is a collection of named action command strings to enable their re-use when it's convenient. Their `effect` is identification to a filteredAction action.
116116

117117
Options
118118
-----------
119119

120-
A number of profile wide options exist to allow further configuration of specific behavour.
120+
A number of profile wide options exist to allow further configuration of specific behaviour.
121121

122122
- twitchMysterSubGiftMode - When Twitch Subscription Mystery Gifts are given out by a viewer to random other viewers the event can either be reacted to for the donator or receiver. The program's default is the `donator` value if the setting isn't specified in the profile's options. If the Streamlabs event is reacted to by a `money` valueType reaction, rather than a twitch subscriber specified reaction, it will obey this setting so only 1 reaction is triggered. Meaning the other event type won't be triggered for Twitch Subscription Mystery Gifts to avoid duplicate reactions.
123123
- `donator` - React to it as one large donation using the `subMysteryGift` event reaction.
124124
- `receiver` - React to each viewer getting the gifted subscription using the `subscriptionGift` event reaction.
125+
YES this setting has a typo in it.
125126

126127

127128
Profile Creation Notes
128129
--------------------
129130

130131
### Profile attribute values, quotes and quote escaping
131132

132-
All data attributes used in scripts are replaced with their event data values at execution time. The replaced text may require wrapping in quotes if it needs to be treated as a string when it is recieved by the game through the RCON command.
133+
All data attributes used in scripts are replaced with their event data values at execution time. The replaced text may require wrapping in quotes if it needs to be treated as a string when it is received by the game through the RCON command.
133134

134-
However, the profile file is defined using JSON syntax and so all text strings must be wrapped in double quotes `"` within the profile. Single quotes can be used within a JSON string without the need to escape them, and are advised for this reason where possible. If you need to use a double quote within a text string it must be escaped with a backslash `\`. In some cases single quotes may not be accepted by the game/mod recieveing the RCON command, and so escaped double quotes would have to be used, i.e. a mod expects a JSON string as an argument.
135+
However, the profile file is defined using JSON syntax and so all text strings must be wrapped in double quotes `"` within the profile. Single quotes can be used within a JSON string without the need to escape them, and are advised for this reason where possible. If you need to use a double quote within a text string it must be escaped with a backslash `\`. In some cases single quotes may not be accepted by the game/mod receiving the RCON command, and so escaped double quotes would have to be used, i.e. a mod expects a JSON string as an argument.
135136

136137
Data attribute values will be made safe by the program; with any single or double quotes either being removed by Python automatically or escaped with a backslash before being used as part of a Rcon command. If you require a single or double quote to be received by Rcon escaped then you must escape it with 2 backslashes `\\'`. See the `Factorio - Advanced Usage Example.json` for examples of the some of these combinations.
137138

@@ -184,7 +185,7 @@ The program has a `config.json` that stores its global configuration. The settin
184185
1. "API Settings" tab.
185186
1. "API Token" on inner tab.
186187
1. There's then the "Your Socket API Token".
187-
- Profile Default - The name of the profile json file that will be selected on loading the application. Profiel can be reselected once loaded.
188+
- Profile Default - The name of the profile json file that will be selected on loading the application. Profile can be reselected once loaded.
188189
- Rcon Server Address - The URL/IP address of your game server. Must be reachable from where you are running this application.
189190
- Rcon Server Port - The port that RCON is running on, on your game server. Must be reachable from where you are running this application.
190191
- Rcon Server Password - The password you set in your game, or can be blank if no password was set (not advised).
@@ -198,7 +199,7 @@ Development Building
198199
Uses the python modules and their dependencies. Built and tested against these old versions:
199200

200201
- Python 3.7.3 32bit - default install modules = https://www.python.org/downloads/release/python-373
201-
- python-engineio 3.5.1 (pre-req of socketio, but if not done first the wrong dependant versin gets installed by socketio) = pip install python-engineio==3.5.1
202+
- python-engineio 3.5.1 (pre-requisite of socketio, but if not done first the wrong dependant version gets installed by socketio) = pip install python-engineio==3.5.1
202203
- python-socketio[client] 4.0.1 = https://python-socketio.readthedocs.io/en/latest = pip install python-socketio[client]==4.0.1
203204
- PyInstaller 3.4 = https://www.pyinstaller.org = pip install -U pyinstaller==3.4
204205
- MCRcon 0.5.2 = https://github.com/uncaught-exceptions/mcrcon = pip install mcrcon==0.5.2

Source/Streamlabs Rcon Integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
class State():
1818
def __init__(self):
19-
self.version = "0.1.3"
19+
self.version = "0.1.4"
2020
self.config = Config(self)
2121
self.logging = Logging(self)
2222
self.config.LogMissingSettings()

Source/StreamlabsEvent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def PopulateNormalisedData(self):
152152
self.state.RecordActivity(self.state.translations.GetTranslation(
153153
"StreamlabsEvent UnrecognisedTwitchSubscriptionType") + subPlan)
154154
return False
155-
self.state.mysterySubGifts[self.bestName] = amount
155+
self.state.mysterySubGifts[self.rawMessage["gifter"]] = amount # Has to be the gifter username as this is the field ew get in all the events, the display name of the gifter isn't always present.
156156
elif (self.handlerName == "youtube_account-subscription"):
157157
self.valueType = "money"
158158
self.value = 5

Source/TestEvents.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,14 @@ def GenerateTestEventArray(eventPlatform, eventType, value, special, payloadCoun
7878
primaryEvent = TestEventUtils._GenerateTestEvent(
7979
eventPlatform, eventType, value, special, payloadCount)
8080
testEventArray = [primaryEvent]
81+
82+
# Twitch sends events for the giver and also each receiver.
8183
if eventPlatform == "Twitch" and eventType == "Give Random Gift Subscriptions":
82-
for i in range(special):
84+
for i in range(special):
8385
childEvent = TestEventUtils._GenerateTestEvent(
8486
eventPlatform, "Give Specific Gift Subscription", value, i+2, 1)
8587
testEventArray.append(childEvent)
88+
8689
return testEventArray
8790

8891
@staticmethod
@@ -219,7 +222,7 @@ def EventMessageConstructor(value, special, iterator):
219222
usernameLowerCase = 'user' + str(iterator)
220223
messageEventId = TestEventUtils.GenerateUuidNoHyphens()
221224
return {
222-
'sub_plan': str(value),
225+
'sub_plan': TestEventUtils.TwitchSubscriptionSubPlanValueToString(value),
223226
'sub_type': 'submysterygift',
224227
'gifter': usernameLowerCase,
225228
'gifter_display_name': usernameCamalCase,

Source/eventDefinitions.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
}
9595
},
9696
"twitch_account-subscriptionGift": {
97-
"_comment": "When a user is gifted a subscription. If the gift was too the community and not the specific viewer then the 'twitchMysterSubGiftMode' option must be set to 'receiver' in the profile for this event to be triggered in this situation.",
97+
"_comment": "When a user is gifted a subscription. If the gift was to the community and not the specific viewer then the 'twitchMysterSubGiftMode' option must be set to 'receiver' in the profile for this event to be triggered in this situation.",
9898
"name": {
9999
"valueType": "text string",
100100
"description": "the username of the person who received the subscription"
@@ -118,7 +118,8 @@
118118
"gifter": {
119119
"valueType": "text string",
120120
"description": "the username of the person who gifted the subscription"
121-
}
121+
},
122+
"_comment_gifter_display_name": "There is no display name exposed by twitch for this event. So we can only use the gifters username (un-formatted)."
122123
},
123124
"twitch_account-subMysteryGift": {
124125
"_comment": "When a user gifts a number of subscriptions to the community. The 'twitchMysterSubGiftMode' option must be set to 'donator' in the profile for this event to be triggered.",

ToDo.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
Bugs / Outstanding
22
===================
33

4-
Back in commit 402ff1a0a6efe40532fb6e523184eb4f974e0c92 I changed it so that both bespoke reactions and generic reactions ran for the same event. This was a mistake and I did it as a simple fix for what JD wanted to do at the time. I should reverse this change and add a new option for this type of usage case. As its breaking standard behavour for more normal usage scenarios. Also I never updated all the Readme for it.
4+
Back in commit 402ff1a0a6efe40532fb6e523184eb4f974e0c92 I changed it so that both bespoke reactions and generic reactions ran for the same event. This was a mistake and I did it as a simple fix for what JD wanted to do at the time. I should reverse this change and add a new option for this type of usage case. As its breaking standard behaviour for more normal usage scenarios. Also I never updated all the Readme for it.
55
I couldn't use negative filtering by type on a money reaction: [TYPE] != 'subscription' and [TYPE] != 'subMysteryGift'
66
Document that you can add comments within the profile if you want. The tool never looks for a "comment" key in the JSON. The tool only looks for the documented keys in the JSON with anything else being ignored.
77
Replace the event definitions with a proper readme type file. Also add to readme what the generic event types are.
88
The profiles loading tries to do everything in Profiles folder, no sanity check about file/folder type. If you make a "backup" folder in it, the program crashes without recording an error.
99
Look to use yaml in RCON integration configs as they may be nicer to read and may support the action commands and passing JSON to Factorio nicer.
10-
Should I just ignore any event without an ID string? Came up ages ago during Will's playthrough. But not enough of an issue to be done at the time.
10+
Should I just ignore any event without an ID string? Came up ages ago during Will's play through. But not enough of an issue to be done at the time.
1111
If you close the GUI when internet is dead after being connected via RCON the python window never closes. Guess its waiting for something to close.
1212
Change profile loading to not error on startup for bad profiles, but error on trying to start them.
13+
Document that to call a named `action` in the `reactions` you need to pre-fix it with ACTION_, i.e. ACTION_myActionName. The `actions` array `name` field stays as just the name, i.e. myActionName. It must also be wrapped in "[]" just like any other special field. The `effect` of the shared action will only accept `ALL` type fields, so can't use any event type specific fields.
14+
Correct "twitchMysterSubGiftMode" to not have a typo in it, readme and code. Add a changelog note for it and also make it error if the old bad spelling is in a config to ensure users update and thus get their desired setting.
15+
Lots of internal code typos throughout the project that need updating.
1316

1417

1518
Ideas

0 commit comments

Comments
 (0)