-
Notifications
You must be signed in to change notification settings - Fork 1
/
Bankaccount_StreamlabsSystem.py
331 lines (270 loc) · 13.6 KB
/
Bankaccount_StreamlabsSystem.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
#!/usr/bin/python
# -*- coding: utf-8 -*-
#---------------------------
# Import Libraries
#---------------------------
import os
import sys
import json
import time
import collections
from pprint import pprint
from shutil import copyfile
import clr
clr.AddReference("IronPython.SQLite.dll")
clr.AddReference("IronPython.Modules.dll")
# Load own modules
sys.path.append(os.path.dirname(__file__)) # point at current folder for classes / references
sys.path.append(os.path.join(os.path.dirname(__file__), "ba_lib")) # point at lib folder for classes / references
from ba_definitions import ROOT_DIR
import ba_config
import miscLib
#---------------------------
# [Required] Script Information (must be existing in this main file)
# TODO: Some stuff from here should be moved to a GUI settings file later
#---------------------------
ScriptName = ba_config.ScriptName
Website = ba_config.Website
Description = ba_config.Description
Creator = ba_config.Creator
Version = ba_config.Version
#############################################
# START: Generic Chatbot functions
#############################################
#---------------------------
# [Required] Initialize Data (Only called on load of script)
#---------------------------
def Init():
# generate data and archive directory if they don't exist (uses DataBackupPath because it includes the data path)
if (False == os.path.isdir(ba_config.DataBackupPath)):
os.makedirs(ba_config.DataBackupPath)
# Creates an empty data file if it doesn't exist
if (False == os.path.isfile(ba_config.DataFilepath)):
# generate empty data file and save it
data = {}
with open(ba_config.DataFilepath, 'w') as f:
json.dump(data, f, indent=4)
Log("Bankaccount script successfully initialized")
return
#---------------------------
# [Required] Execute Data / Process messages
#---------------------------
def Execute(data):
response = "Error, try '!bank help' for more information"
# bankaccount command called
if (data.IsChatMessage() and data.GetParam(0).lower() == ba_config.CommandMain):
userPoints = int(Parent.GetPoints(data.User))
userAccountbalance = GetBalance(data.User)
bankCommand = data.GetParam(1).lower()
pointsAmount = data.GetParam(2)
if (bankCommand == ba_config.CommandHelp):
Parent.SendStreamMessage(ba_config.ResponseHelp)
return
if (bankCommand == ba_config.CommandBalance):
Log(GetBalance(data.User))
if ("error" != GetBalance(data.User)):
response = "Your current bank account balance: " + miscLib.FormatThousandsSeparator(GetBalance(data.User)) + " " + ba_config.CurrencyName
else:
response = "Error: you don't have a bank account yet!"
Parent.SendStreamMessage(response)
return
if (bankCommand == ba_config.CommandTop10Richest):
Parent.SendStreamMessage(ba_config.ResponseTop10Richest + GetTop10RichestWithData(False))
return
if (bankCommand == ba_config.CommandTop10RichestAllTime):
Parent.SendStreamMessage(ba_config.ResponseTop10Richest + GetTop10RichestWithData(True))
return
if (pointsAmount and not pointsAmount.isdigit()):
Parent.SendStreamMessage("Error: Only numbers you silly!")
return
if (bankCommand == ba_config.CommandDeposit):
if (pointsAmount > 0):
# check if user has enough points to deposit
if (int(userPoints) >= int(pointsAmount)):
UpdateDatafile(bankCommand, data)
response = "Successfully deposited " + miscLib.FormatThousandsSeparator(pointsAmount) + " " + ba_config.CurrencyName + "! | Current cash: " + miscLib.FormatThousandsSeparator(Parent.GetPoints(data.User)) + " " + ba_config.CurrencyName + " | Current balance: " + miscLib.FormatThousandsSeparator(GetBalance(data.User)) + " " + ba_config.CurrencyName
else:
response = "Error: not enough cash to deposit " + miscLib.FormatThousandsSeparator(pointsAmount) + " " + ba_config.CurrencyName + "! | Current cash: " + str(userPoints)
if (bankCommand == ba_config.CommandWithdraw):
if (int(pointsAmount) > 0):
# check if user has enough account balance for withdrawal
if (userAccountbalance >= int(pointsAmount)):
UpdateDatafile(bankCommand, data)
response = "Successfully withdrawn " + miscLib.FormatThousandsSeparator(pointsAmount) + " " + ba_config.CurrencyName + "! | Current cash: " + miscLib.FormatThousandsSeparator(Parent.GetPoints(data.User)) + " " + ba_config.CurrencyName + " | Current balance: " + miscLib.FormatThousandsSeparator(GetBalance(data.User)) + " " + ba_config.CurrencyName
else:
response = "Insufficient account balance for withdrawal of " + miscLib.FormatThousandsSeparator(pointsAmount) + " " + ba_config.CurrencyName + "! | Current balance: " + miscLib.FormatThousandsSeparator(userAccountbalance) + " " + ba_config.CurrencyName
Parent.SendStreamMessage(response) # Send your message to chat
return
#---------------------------
# [Required] Tick method (Gets called during every iteration even when there is no incoming data)
# Runs basically every millisecond since the script is activated^^
#---------------------------
def Tick():
return
#---------------------------
# [Optional] Parse method (Allows you to create your own custom $parameters)
# Here's where the magic happens, all the strings are sent and processed through this function
#
# Parent.FUNCTION allows to use functions of the Chatbot and other outside APIs (see: https://github.com/AnkhHeart/Streamlabs-Chatbot-Python-Boilerplate/wiki/Parent)
#
# ORIGINAL DEF: def Parse(parseString, userid, username, targetid, targetname, message):
#---------------------------
def Parse(parseString, command, data):
# after every necessary variable was processed: return the whole parseString, if it wasn't already
return parseString
#---------------------------
# [Optional] Reload Settings (Called when a user clicks the Save Settings button in the Chatbot UI)
#---------------------------
def ReloadSettings(jsonData):
return
#---------------------------
# [Optional] Unload (Called when a user reloads their scripts or closes the bot / cleanup stuff)
#---------------------------
def Unload():
Log("Script unloaded")
BackupDataFile()
return
#---------------------------
# [Optional] ScriptToggled (Notifies you when a user disables your script or enables it)
#---------------------------
def ScriptToggled(state):
return
#############################################
# END: Generic Chatbot functions
#############################################
#---------------------------
# Log helper (For logging into Script Logs of the Chatbot)
# Note that you need to pass the "Parent" object and use the normal "Parent.Log" function if you want to log something inside of a module
#---------------------------
def Log(message):
Parent.Log(ScriptName, str(message))
return
#---------------------------
# UpdateDataFile: Function for modfiying the file which contains the data, see data/bankdata.json
# returns the parseString for parse(Function)
#---------------------------
def UpdateDatafile(command, data):
currentday = miscLib.GetCurrentDayFormattedDate()
success = False
userId = str(data.User)
userName = str(data.UserName.lower())
pointsAmount = int(data.GetParam(2))
# this loads the data of file bankdata.json into variable "data"
with open(ba_config.DataFilepath, 'r') as f:
data = json.load(f)
# check if the given data.user exists in data. -> user doesnt exist yet, create array of the default user data, which will be stored in bankdata.json
if (True == IsNewUser(userName)):
data[userName] = {}
data[userName][ba_config.JSONVariablesBalance] = 0
data[userName][ba_config.JSONVariablesLatestDeposit] = 0
data[userName][ba_config.JSONVariablesLatestDepositDate] = ""
data[userName][ba_config.JSONVariablesLatestWithdrawal] = 0
data[userName][ba_config.JSONVariablesLatestWithdrawalDate] = ""
data[userName][ba_config.JSONVariablesHighestBalance] = 0
data[userName][ba_config.JSONVariablesHighestBalanceDate] = ""
if (command == ba_config.CommandDeposit):
data[userName][ba_config.JSONVariablesBalance] += pointsAmount
data[userName][ba_config.JSONVariablesLatestDeposit] = pointsAmount
data[userName][ba_config.JSONVariablesLatestDepositDate] = currentday
Parent.RemovePoints(userId,userName,pointsAmount)
success = True
# if new balance is higher than old balance
if (int(data[userName][ba_config.JSONVariablesBalance]) > int(data[userName][ba_config.JSONVariablesHighestBalance])):
data[userName][ba_config.JSONVariablesHighestBalance] = data[userName][ba_config.JSONVariablesBalance]
data[userName][ba_config.JSONVariablesHighestBalanceDate] = currentday
if (command == ba_config.CommandWithdraw):
data[userName][ba_config.JSONVariablesBalance] -= pointsAmount
data[userName][ba_config.JSONVariablesLatestWithdrawal] = pointsAmount
data[userName][ba_config.JSONVariablesLatestWithdrawalDate] = currentday
Parent.AddPoints(userId,userName,pointsAmount)
success = True
# after everything was modified and updated, we need to write the stuff from our "data" variable to the bankdata.json file
os.remove(ba_config.DataFilepath)
with open(ba_config.DataFilepath, 'w') as f:
json.dump(data, f, indent=4)
return success
#---------------------------
# returns the string formatted balance
#---------------------------
def GetBalance(username):
with open(ba_config.DataFilepath, 'r') as f:
data = json.load(f)
if str(username.lower()) not in data:
balanceResponse = "error"
else:
balanceResponse = data[username.lower()][ba_config.JSONVariablesBalance]
return balanceResponse
#---------------------------
# IsNewUser
#---------------------------
def IsNewUser(username):
# this loads the data of file bankdata.json into variable "data"
with open(ba_config.DataFilepath, 'r') as f:
data = json.load(f)
if str(username.lower()) not in data:
return True
else:
return False
#---------------------------
# BackupDataFile
#
# Backups the data file in the "archive" folder with current date and timestamp for ease of use
#---------------------------
def BackupDataFile():
if (True == os.path.isfile(ba_config.DataFilepath)):
if (False == os.path.isdir(ba_config.DataBackupPath)):
os.makedirs(ba_config.DataBackupPath)
dstFilename = ba_config.DataBackupFilePrefix + str(miscLib.GetCurrentDayFormattedDate()) + "_" + str(int(time.time())) + ".json"
dstFilepath = os.path.join(ba_config.DataBackupPath, dstFilename)
copyfile(ba_config.DataFilepath, dstFilepath)
return
#---------------------------
# GetTop10Richest
#
# Returns a list of all top 10 richest users sorted by balance to be iterated
# Param: "alltime = TRUE" returns the alltime top10richest (highest balance ever)
#---------------------------
def GetTop10Richest(alltime):
with open(ba_config.DataFilepath, 'r') as f:
data = json.load(f)
# build sortableDict with user and balances like "user: balance"
sortableRichestDict = {}
for user in data:
# different list if alltime = True
if (True == alltime):
sortableRichestDict[user] = data[user][ba_config.JSONVariablesHighestBalance]
else:
sortableRichestDict[user] = data[user][ba_config.JSONVariablesBalance]
# sort it by checkins and put it in a list of max 10 items
sortedRichestList = sorted(sortableRichestDict.items(), key=lambda x: x[1], reverse=True)
sortedRichestDict = collections.OrderedDict(sortedRichestList)
# only the first 10 items
return sortedRichestDict.keys()[:10]
#---------------------------
# GetTop10RichestWithData
#
# Returns a complete string of all top 10 richest users sorted by balance and with data
# Param: bool "alltime = TRUE" returns the alltime top10richest (highest balance ever)
#---------------------------
def GetTop10RichestWithData(alltime):
top10richest = GetTop10Richest(alltime)
top10RichestWithData = ""
# get data for response
with open(ba_config.DataFilepath, 'r') as f:
data = json.load(f)
position = 0
for richestUser in top10richest:
position += 1
top10RichestWithData += "#" + str(position) + " "
top10RichestWithData += str(richestUser)
top10RichestWithData += " ("
# different output, when alltime = True
if (True == alltime):
top10RichestWithData += miscLib.FormatThousandsSeparator(data[richestUser][ba_config.JSONVariablesHighestBalance]) + " " + ba_config.CurrencyName + " at " + str(data[richestUser][ba_config.JSONVariablesHighestBalanceDate])
else:
top10RichestWithData += miscLib.FormatThousandsSeparator(data[richestUser][ba_config.JSONVariablesBalance]) + " " + ba_config.CurrencyName
top10RichestWithData += ")"
# only display dash below last position
if (position < 10):
top10RichestWithData += " - "
return top10RichestWithData