class guestLounge(ts3plugin): path = getScriptPath(__name__) name = "Guest Lounges" apiVersion = 22 requestAutoload = False version = "1.0" author = "Bluscream" description = "" offersConfigure = False commandKeyword = "" infoTitle = None hotkeys = [] menuItems = [] timer = QTimer() ts3host = None """ cfg = ConfigParser() cfg["9lBVIDJRSSgAGy+cWJgNlUQRd64="] = { "enabled": True } """ def __init__(self): if "aaa_ts3Ext" in PluginHost.active: ts3ext = PluginHost.active["aaa_ts3Ext"] self.ts3host = ts3ext.ts3host self.tabs = ts3ext.tabs else: retry = 1000 self.timer.singleShot(retry, self.__init__) ts3lib.printMessageToCurrentTab("{}: [color=red]Dependency not yet loaded, retrying in {} second(s)!".format(self.name, retry/1000)) return if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded.".format(timestamp(),self.name,self.author)) def stop(self): if hasattr(self, "timer"): if self.timer.isActive(): self.timer.stop() del self.timer def onClientMoveEvent(self, schid, clid, oldChannelID, newChannelID, visibility, moveMessage): client = self.ts3host.getUser(schid, clid) if client.server.me.channel.cid if not client.server.me.getChannelGroupId() in [self.tabs[schid]["channelModGroup"], client.server.defaultChannelAdminGroup]: return if clientID in self.waiting and (newChannelID == 0 or newChannelID == self.mychan): # if newChannelID == self.mychan: # (err, dbid) = ts3lib.getClientVariable(schid, clientID, ts3defines.ClientPropertiesRare.CLIENT_DATABASE_ID) ts3lib.printMessage(schid, "{}: [color=orange]Removing channel mod from {}".format(self.name, self.waiting[clientID] if newChannelID == 0 else clientURL(schid, clientID)), ts3defines.PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) ts3lib.requestSetClientChannelGroup(schid, [self.sgid_guest], [self.mychan], [self.waiting[clientID]]) del self.waiting[clientID] return if newChannelID == 0 or oldChannelID != 0: return (err, sgids) = ts3lib.getClientVariableAsString(schid, clientID, ts3defines.ClientPropertiesRare.CLIENT_SERVERGROUPS) if not self.sgid_guest in intList(sgids): return # TODO Any way to get the cgid in another channel? (err, uid) = ts3lib.getClientVariable(schid, clientID, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) if getContactStatus(uid) == ContactStatus.BLOCKED: ts3lib.printMessage(schid, "{}: [color=red]Not allowing blocked user {} in your channel.".format(self.name, clientURL(schid, clientID)), ts3defines.PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) return (err, dbid) = ts3lib.getClientVariable(schid, clientID, ts3defines.ClientPropertiesRare.CLIENT_DATABASE_ID) self.waiting[clientID] = dbid ts3lib.printMessage(schid, "{}: [color=green]Found new guest {} giving him channel mod until he's here ;)".format(self.name, clientURL(schid, clientID)), ts3defines.PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) ts3lib.requestSetClientChannelGroup(schid, [self.cgid_mod], [self.mychan], [dbid])
class spacify(ts3plugin): path = getScriptPath(__name__) name = "Spacify" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 22 requestAutoload = False version = "1.0" author = "Bluscream" description = "" offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [] hotkeys = [] widget = None last = "" # ignore = False def __init__(self): self.widget = widget("ChatLineEdit") result = self.widget.connect("textChanged()", self.textEdited) print("Result", result) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded.".format(timestamp(),self.name,self.author)) def stop(self): self.widget.disconnect("textChanged()", self.textEdited) def textEdited(self): text = self.widget.toPlainText() if not text.endswith(" "): self.widget.insert(" ") # self.widget.cursorPosition(len(text)+1) # self.ignore = True self.last = self.widget.toPlainText()
class autoJoin(ts3plugin): path = getScriptPath(__name__) name = "Auto Join" try: apiVersion = getCurrentApiVersion() except: apiVersion = 21 requestAutoload = True version = "1.0" author = "Bluscream" description = "" offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [(ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 0, name, "")] hotkeys = [] schid = 0 request_tp = False def __init__(self): if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded.".format(timestamp(), self.name, self.author)) def onMenuItemEvent(self, schid, atype, menuItemID, selectedItemID): if atype != ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL or menuItemID != 0: return if schid == self.schid: self.schid = 0; ts3lib.printMessageToCurrentTab("{} > Disabled!".format(self.name)) else: self.schid = schid; ts3lib.printMessageToCurrentTab("{} > Enabled for tab #{}!".format(self.name,schid)) def onNewChannelCreatedEvent(self, schid, cid, channelParentID, invokerID, invokerName, invokerUniqueIdentifier): if schid != self.schid: print(cid, "schid != self.schid"); return (err, ownID) = ts3lib.getClientID(schid) if invokerID == ownID: print(cid, "invokerID == ownID"); return if isPermanent(schid, cid) or isSemiPermanent(schid, cid): print("isPermanent(schid, cid) or isSemiPermanent(schid, cid)"); return (error, maxclients) = ts3lib.getChannelVariable(schid, cid, ts3defines.ChannelProperties.CHANNEL_MAXCLIENTS) # (error, maxfamilyclients) = ts3lib.getChannelVariable(schid, cid, ts3defines.ChannelProperties.CHANNEL_MAXFAMILYCLIENTS) if maxclients != -1: clients = channelClientCount(schid, cid) if clients >= maxclients: print(cid, "clients >= maxclients"); return (err, needed_tp) = ts3lib.getChannelVariable(schid, cid, ts3defines.ChannelPropertiesRare.CHANNEL_NEEDED_TALK_POWER) if needed_tp >=0: (err, ownTP) = ts3lib.getClientSelfVariable(schid, ts3defines.ClientPropertiesRare.CLIENT_TALK_POWER) if int(ownTP) < needed_tp: self.request_tp = True (err, pw) = ts3lib.getChannelVariable(schid, cid, ts3defines.ChannelProperties.CHANNEL_FLAG_PASSWORD) if err == ts3defines.ERROR_ok and pw: pw = getChannelPassword(schid, cid, False, False, True) # ts3lib.verifyChannelPassword(schid, cid, pw, "passwordCracker:manual") if not pw: print(cid, "not pw"); return status = getContactStatus(invokerUniqueIdentifier) if status == ContactStatus.BLOCKED: print(cid, invokerUniqueIdentifier, "blocked"); return ts3lib.printMessage(schid, "{} > Joining into {}".format(self.name,channelURL(schid, cid)), ts3defines.PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) ts3lib.requestClientMove(schid, ownID, cid, pw if pw else "123") def onClientMoveEvent(self, schid, clientID, oldChannelID, newChannelID, visibility, moveMessage): if schid != self.schid: return (err, ownID) = ts3lib.getClientID(schid) if clientID != ownID: return if not self.request_tp: return self.request_tp = False (err, needed_tp) = ts3lib.getChannelVariable(schid, newChannelID, ts3defines.ChannelPropertiesRare.CHANNEL_NEEDED_TALK_POWER) if needed_tp >=0: (err, ownTP) = ts3lib.getClientSelfVariable(schid, ts3defines.ClientPropertiesRare.CLIENT_TALK_POWER) if int(ownTP) < needed_tp: ts3lib.requestIsTalker(schid, True, "")
class banWhitelist(ts3plugin): path = getScriptPath(__name__) name = "Ban Whitelist" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 22 requestAutoload = False version = "1.0" author = "Bluscream" description = "Automatically removes whitelisted IPs from the banlist" offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [] hotkeys = [] suid = "9lBVIDJRSSgAGy+cWJgNlUQRd64=" requested = 0 whitelist = [] def __init__(self): if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def onClientBanFromServerEvent(self, schid, clid, oldChannelID, newChannelID, visibility, kickerID, kickerName, kickerUniqueIdentifier, time, kickMessage): active = PluginHost.active if not "Custom Ban" in active: return (err, suid) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerProperties.VIRTUALSERVER_UNIQUE_IDENTIFIER) if suid != self.suid: return self.requested = schid self.whitelist = active["Custom Ban"].whitelist if len(self.whitelist) < 1: return ts3lib.requestBanList(schid) def onBanListEvent(self, schid, banid, ip, name, uid, creationTime, durationTime, invokerName, invokercldbid, invokeruid, reason, numberOfEnforcements, lastNickName): if self.requested != schid: return if not ip in self.whitelist: return ts3lib.printMessageToCurrentTab( "{}: [color=red]Unbanning whitelisted IP [b]{}".format( self.name, ip)) ts3lib.bandel(schid, banid)
class TS3AB(ts3plugin): path = getScriptPath(__name__) name = "TS3AB" try: apiVersion = getCurrentApiVersion() except: apiVersion = 21 requestAutoload = False version = "1.0" author = "Bluscream" description = "" offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [] hotkeys = [] def __init__(self): if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def onClientMoveEvent(self, schid, clientID, oldChannelID, newChannelID, visibility, moveMessage): (err, ownID) = ts3lib.getClientID(schid) if clientID != ownID: return (err, needed_tp) = ts3lib.getChannelVariable( schid, newChannelID, ts3defines.ChannelPropertiesRare.CHANNEL_NEEDED_TALK_POWER) if needed_tp >= 0: # (err, hasTP) = ts3lib.getClientSelfVariable(schid, ts3defines.ClientPropertiesRare.CLIENT_IS_TALKER) (err, ownTP) = ts3lib.getClientSelfVariable( schid, ts3defines.ClientPropertiesRare.CLIENT_TALK_POWER) if int(ownTP) < needed_tp: ts3lib.requestSendPrivateTextMsg( schid, self.text, self.servers[schid]["clid"], self.retcode) # ts3lib.requestIsTalker(schid, True, "")
class quickPerm(ts3plugin): path = getScriptPath(__name__) name = "Quick Permissions" try: apiVersion = getCurrentApiVersion() except: apiVersion = 21 requestAutoload = False version = "1.0" author = "Bluscream" description = "Stolen from NoX by exp111" offersConfigure = False commandKeyword = "perm" infoTitle = None menuItems = [] hotkeys = [] retcodes = {} perms = {} # "success": 0, "fail": 0, "processed": 0, "stop": False flood = False p = () def __init__(self): if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def processCommand(self, schid, keyword): args = keyword.split(' ') cmd = args.pop(0).lower() (err, clid) = ts3lib.getClientID(schid) (err, cldbid) = ts3lib.getClientVariable( schid, clid, ClientPropertiesRare.CLIENT_DATABASE_ID) if cmd == "grant": # if len(perm) < 2: return False # if len(perm) == 2: perm.append(False).append(False) skip = args[2] if len(args) > 2 else False val = boolean(args[1]) if len(args) > 1 else True perm = args[0] (err, pid) = ts3lib.getPermissionIDByName(schid, perm) ts3lib.printMessageToCurrentTab("Requesting \"{}\" ({})".format( perm, pid)) ts3lib.requestClientAddPerm(schid, cldbid, [pid], [val], [skip]) (err, ownCID) = ts3lib.getChannelOfClient(schid, clid) ts3lib.requestChannelClientAddPerm(schid, ownCID, cldbid, [pid], [val]) elif cmd == "essential": self.getPerms(schid) elif cmd == "full": self.getFullPerms(schid) elif cmd == "build": _file = args.pop(0) self.p = self.buildLists( path.join(self.path, "{}.csv".format(_file)), schid) length = len(self.p[0]) print("ids", length, "vals", len(self.p[1]), "skips", len(self.p[2]), "negates", len(self.p[3])) print("\nIDs:\n", self.p[0]) print("\nvals:\n", self.p[1]) print("\nskips:\n", self.p[2]) print("\nnegates:\n", self.p[3]) ts3lib.printMessageToCurrentTab( "Loaded {} permissions".format(length)) elif cmd == "client": each = len(args) if not each: ts3lib.requestClientAddPerm(schid, cldbid, self.p[0], self.p[1], self.p[2]) else: length = len(self.p[0]) for x in range(length): ts3lib.requestClientAddPerm(schid, cldbid, [self.p[0][x]], [self.p[1][x]], [self.p[2][x]]) elif cmd in ["channelclient", "clientchannel"]: (err, ownCID) = ts3lib.getChannelOfClient(schid, clid) each = len(args) if not each: ts3lib.requestChannelClientAddPerm(schid, ownCID, cldbid, self.p[0], self.p[1]) else: length = len(self.p[0]) for x in range(length): ts3lib.requestChannelClientAddPerm(schid, ownCID, cldbid, [self.p[0][x]], [self.p[1][x]]) elif cmd == "channel": (err, ownCID) = ts3lib.getChannelOfClient(schid, clid) ts3lib.ts3lib.requestChannelAddPerm(schid, ownCID, self.p[0], self.p[1]) elif cmd == "sgroup": sgid = int(args.pop(0)) ts3lib.requestServerGroupAddPerm(schid, sgid, 1, self.p[0], self.p[1], self.p[2], self.p[3]) elif cmd == "cgroup": cgid = int(args.pop(0)) ts3lib.requestChannelGroupAddPerm(schid, cgid, 1, self.p[0], self.p[1]) elif cmd == "id": (err, pid) = ts3lib.getPermissionIDByName(schid, args[0]) ts3lib.printMessageToCurrentTab("{} = [b]{}".format(args[0], pid)) elif cmd == "sgadd": sgid = int(args.pop(0)) if len(args): cldbid = int(args.pop(0)) ts3lib.requestServerGroupAddClient(schid, sgid, cldbid) elif cmd == "sgrem": sgid = int(args.pop(0)) if len(args): cldbid = int(args.pop(0)) ts3lib.requestServerGroupDelClient(schid, sgid, cldbid) else: return False return True def onServerGroupClientAddedEvent(self, schid, clid, clientName, clientUniqueIdentity, sgid, invokerClientID, invokerName, invokerUniqueIdentity): if invokerClientID < 1: return (err, ownID) = ts3lib.getClientID(schid) if ownID != clid: return # if invokerClientID == ownID: return (err, dgid) = ts3lib.getServerVariable( schid, VirtualServerPropertiesRare.VIRTUALSERVER_DEFAULT_SERVER_GROUP) if sgid == dgid: return self.getPerms(schid, clid, sgid) """ for sgid in [167,169,165,168]: (err, cldbid) = ts3lib.getClientVariable(schid, clid, ClientPropertiesRare.CLIENT_DATABASE_ID) ts3lib.requestServerGroupDelClient(schid, sgid, cldbid) # ts3lib.requestServerGroupAddPerm(schid, sgid, 1, [166], [75], [0], [0]) """ def getPerms(self, schid, clid=0, sgid=0): if self.flood: return if not clid: (err, clid) = ts3lib.getClientID(schid) (err, cldbid) = ts3lib.getClientVariable( schid, clid, ClientPropertiesRare.CLIENT_DATABASE_ID) self.perms = {"success": 0, "fail": 0, "processed": 0, "stop": False} with open(path.join(self.path, "essential.csv")) as csvfile: permissions = csv.reader(csvfile, delimiter=';') for perm in permissions: if self.perms["stop"]: break (err, pid) = ts3lib.getPermissionIDByName(schid, perm[0]) retcode = ts3lib.createReturnCode() self.retcodes[retcode] = perm[0] v = 100 if sgid == 2 and perm[1] == "75" else int(perm[1]) ts3lib.requestClientAddPerm(schid, cldbid, [pid], [v], [int(perm[2])], retcode) (err, ownCID) = ts3lib.getChannelOfClient(schid, clid) if self.perms["stop"]: break ts3lib.requestChannelClientAddPerm(schid, ownCID, cldbid, [pid], [v], retcode) # ts3lib.requestChannelAddPerm(schid, ownCID, [pid], [v], "quickperm") def getFullPerms(self, schid): (err, clid) = ts3lib.getClientID(schid) (err, cldbid) = ts3lib.getClientVariable( schid, clid, ClientPropertiesRare.CLIENT_DATABASE_ID) with open(path.join(self.path, "full.csv")) as csvfile: perms_full = csv.reader(csvfile, delimiter=';') for perm in perms_full: (err, pid) = ts3lib.getPermissionIDByName(schid, perm[0]) ts3lib.requestClientAddPerm(schid, cldbid, [pid], [int(perm[1])], [int(perm[2])]) def disableFlood(self): self.flood = False def onServerErrorEvent(self, schid, errorMessage, error, returnCode, extraMessage): if not returnCode in self.retcodes: return False reason = "finished" self.perms["processed"] += 1 if error == ERROR_ok: self.perms["success"] += 1 elif error == ERROR_client_is_flooding: self.perms["fail"] += 1 self.perms["stop"] = True reason = "failed because of flooding" elif error in [ ERROR_permissions_client_insufficient, ERROR_permissions_insufficient_group_power, ERROR_permissions_insufficient_permission_power ]: self.perms["fail"] += 1 # if self.perms["stop"]: self.retcodes = {} # else: del self.retcodes[returnCode] if not len(self.retcodes): ts3lib.printMessage( schid, "{} {} {}".format(self.name, reason, self.perms), PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) if self.perms["stop"]: self.flood = True QTimer.singleShot(5000, self.disableFlood) elif self.perms["success"] > 0: self.getFullPerms(schid) return True def buildLists(self, file, schid=0): ids = [] vals = [] skips = [] negates = [] grants = [] if not schid: schid = ts3lib.getCurrentServerConnectionHandlerID() with open(file) as csvfile: permissions = csv.DictReader( csvfile, delimiter=';', fieldnames=["Name", "Value", "Skip", "Negate", "Grant"]) for perm in permissions: # if not perm[0].startsWith("i_"): continue (err, pid) = ts3lib.getPermissionIDByName(schid, perm["Name"]) if err != ERROR_ok: continue ids.append(pid) val = int(perm["Value"]) if perm["Value"] else 0 vals.append(val) skip = int(perm["Skip"]) if perm["Value"] else 0 skips.append(skip) neg = int(perm["Negate"]) if perm["Negate"] else 0 negates.append(neg) grant = int(perm["Value"]) if perm["Value"] else 0 if (grant): grantid = perm["Name"].replace( "i_", "i_needed_modify_power_").replace( "b_", "b_needed_modify_power_") grants.append((grantid, grant)) for perm in grants: (err, pid) = ts3lib.getPermissionIDByName(schid, perm[0]) if err != ERROR_ok: continue ids.append(pid) vals.append(perm[1]) skips.append(0) negates.append(0) return (ids, vals, skips, negates)
class antiAFK(ts3plugin): path = getScriptPath(__name__) name = "Anti AFK" try: apiVersion = getCurrentApiVersion() except: apiVersion = 21 requestAutoload = False version = "1.0" author = "Bluscream" description = "Never get moved by being AFK again." offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [(ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 0, "Toggle " + name, "")] hotkeys = [] timer = QTimer() servers = {} text = "." #~cmdclientupdate interval = { "9Sx6wrlRV4i9klBiTanrksNFKvs=": (5, 10), "QTRtPmYiSKpMS8Oyd4hyztcvLqU=": (30, 120), "default": (10, 30) } retcode = "" hook = False def __init__(self): addons = getAddons() for k in addons: if addons[k]["name"] == "TS3Hook": self.hook = True break self.timer.timeout.connect(self.tick) self.timer.setTimerType(2) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def stop(self): for schid in self.servers: self.delTimer(schid) def addTimer(self, schid): err, clid = ts3lib.getClientID(schid) self.servers[schid] = {"clid": clid} interval = self.getInterval(schid) if len(self.servers) == 1: self.timer.start(interval["interval"]) ts3lib.printMessageToCurrentTab( "{}> Enabled for tab #{} with interval {} (server uid: {})".format( self.name, schid, interval["interval"], interval["suid"])) def getInterval(self, schid=0): if schid < 1: schid = ts3lib.getCurrentServerConnectionHandlerID() (err, suid) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerProperties.VIRTUALSERVER_UNIQUE_IDENTIFIER) if not suid in self.interval: suid = "default" min = self.interval[suid][0] * 1000 max = self.interval[suid][1] * 1000 _return = { "schid": schid, "suid": suid, "min": min, "max": max, "interval": randint(min, max) } if PluginHost.cfg.getboolean("general", "verbose"): print(_return) return _return def delTimer(self, schid): if schid in self.servers: # print(self.name, "> Removing Timer:", self.servers[schid], "for #", schid, "(servers:", len(self.servers)-1,")") del self.servers[schid] if len(self.servers) == 0: self.timer.stop() ts3lib.printMessageToCurrentTab("{}> Disabled for tab #{}".format( self.name, schid)) def tick(self): for schid in self.servers: if self.hook: sendCommand(self.name, "clientupdate", schid) else: self.retcode = ts3lib.createReturnCode() ts3lib.requestSendPrivateTextMsg(schid, self.text, self.servers[schid]["clid"], self.retcode) interval = self.getInterval() # print(self.name, ">", "Sent", self.text, "for schid", schid, "to clid", self.servers[schid]["clid"], "| new interval:", interval) self.timer.setInterval(interval) def onMenuItemEvent(self, schid, atype, menuItemID, selectedItemID): if atype != ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL or menuItemID != 0: return if schid in self.servers: self.delTimer(schid) else: self.addTimer(schid) def onConnectStatusChangeEvent(self, schid, newStatus, errorNumber): if newStatus == ts3defines.ConnectStatus.STATUS_DISCONNECTED: self.delTimer(schid) def onTextMessageEvent(self, schid, targetMode, toID, fromID, fromName, fromUniqueIdentifier, message, ffIgnored): if schid in self.servers and fromID == self.servers[schid][ "clid"] and targetMode == ts3defines.TextMessageTargetMode.TextMessageTarget_CLIENT and message == self.text: return 1 def onServerErrorEvent(self, schid, errorMessage, error, returnCode, extraMessage): if returnCode == self.retcode: return True def onServerPermissionErrorEvent(self, schid, errorMessage, error, returnCode, failedPermissionID): if returnCode == self.retcode: return True
class mySupport(ts3plugin): path = getScriptPath(__name__) name = "my Support" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 21 requestAutoload = False version = "1.0" author = "Bluscream" description = "" offersConfigure = False commandKeyword = "ms" infoTitle = None menuItems = [(ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 0, name, "")] hotkeys = [("move_first_from_waiting_room", "Move the first client from your waiting room to your room")] schid = 1 schids = [] waitforchannel = False supchan = 0 perm = (0,"","") cfg = ConfigParser() # cfg.optionxform = str cfg["general"] = { "servername": "Mein Server", "myuid": "e3dvocUFTE1UWIvtW8qzulnWErI=", "mychan": "Vater Channel,Mein Channel" } chan = ConfigParser() chan["props"] = { "maxclients": 1, "codec": ts3defines.CodecType.CODEC_SPEEX_NARROWBAND, "codec_quality": 0, "name open": "Waiting For Support [OPEN]", "name closed": "Waiting For Support [CLOSED]", "name in use": "Waiting For Support [IN USE]" } chan["permissions"] = { "i_channel_needed_modify_power": 75, "i_channel_needed_permission_modify_power": 75, "i_channel_needed_delete_power": 75, "i_channel_needed_subscribe_power": 75, "b_client_request_talker": 0 } def __init__(self): print("test") loadCfg(self.path+"/config.ini", self.cfg) print("test") loadCfg(self.path+"/channel.ini", self.chan) print("test") with open(self.path+"/description.txt", 'r') as myfile: self.description = myfile.read() print("test") self.checkServer(ts3lib.getCurrentServerConnectionHandlerID()) print("test") if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded.".format(timestamp(), self.name, self.author)) def stop(self): pass def onMenuItemEvent(self, schid, atype, menuItemID, selectedItemID): if menuItemID != 0 or atype != ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL: return cid = self.getChannel(schid) if not cid: return ts3lib.requestChannelDelete(schid, cid, True) self.supchan = 0 def processCommand(self, schid, keyword): self.onHotkeyOrCommandEvent(keyword, schid) def onHotkeyEvent(self, keyword): self.onHotkeyOrCommandEvent(keyword) def onHotkeyOrCommandEvent(self, keyword, schid=0): if not schid: schid = ts3lib.getCurrentServerConnectionHandlerID() if not self.schids or len(self.schids) < 1 or schid != self.schids[0] or not self.supchan: return if keyword == "move_first_from_waiting_room": (err, clids) = ts3lib.getChannelClientList(schid, self.supchan) (err, ownID) = ts3lib.getClientID(schid) (err, ownCID) = ts3lib.getChannelOfClient(schid, ownID) ts3lib.requestClientMove(schid, clids[0], ownCID, "") def onConnectStatusChangeEvent(self, schid, newStatus, errorNumber): if newStatus == ts3defines.ConnectStatus.STATUS_CONNECTION_ESTABLISHED: self.schid = schid QTimer.singleShot(10000, self.checkServer) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab(self.name+"> Checking for channel in 10 seconds") elif newStatus == ts3defines.ConnectStatus.STATUS_DISCONNECTED: if schid in self.schids: self.schids.remove(schid) if len(self.schids) < 1 and self.supchan: self.deleteChan() def deleteChan(self): try: import ts3 except ImportError: from devtools import PluginInstaller PluginInstaller().installPackages(['ts3']) import ts3 host=self.cfg.get("serverquery","host") qport=self.cfg.getint("serverquery","qport") client_login_name=self.cfg.get("serverquery","name") client_login_password=self.cfg.get("serverquery","pw") port=self.cfg.getint("serverquery","port") client_nickname=self.cfg.get("serverquery","nick") if hasattr(ts3.query, "TS3ServerConnection"): with ts3.query.TS3ServerConnection(host, qport) as ts3conn: ts3conn.query("login", client_login_name=client_login_name, client_login_password=client_login_password).fetch() ts3conn.query("use", port=port).fetch() ts3conn.query("clientupdate", client_nickname=client_nickname).fetch() ts3conn.query("channeldelete", cid=self.supchan, force=1).fetch() else: with ts3.query.TS3Connection(host, qport) as ts3conn: ts3conn.login(client_login_name=client_login_name, client_login_password=client_login_password) ts3conn.use(port=port) ts3conn.clientupdate(client_nickname=client_nickname) ts3conn.channeldelete(cid=self.supchan, force=True) self.supchan = 0 def checkServer(self, schid=None): if not schid: schid = self.schid (err, servername) = ts3lib.getServerVariable(schid, ts3defines.VirtualServerProperties.VIRTUALSERVER_NAME) (err, ownuid) = ts3lib.getClientSelfVariable(schid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab(self.name+"> Checking for channel....") print("servername:", servername, "cfg:",self.cfg.get("general","servername"), servername == self.cfg.get("general","servername")) print("myuid",ownuid,self.cfg.get("general","myuid"), ownuid == self.cfg.get("general","myuid")) if servername != self.cfg.get("general","servername"): return if ownuid != self.cfg.get("general","myuid"): return print("test1") mychan = self.cfg.get("general", "mychan") # .split(",") return mycid = ts3lib.getChannelIDFromChannelNames(schid, mychan) print("test3") self.schids.append({schid: mycid}) print("test4") self.toggleChannel(schid) def toggleChannel(self, schid): supchan = self.getChannel(schid) if supchan: if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("Channel #%s does exist"%supchan) self.supchan = supchan self.getChannel(schid) else: if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("Channel does not exist, creating...") self.createChannel(schid) def getChannel(self, schid): (err, cids) = ts3lib.getChannelList(schid) for cid in cids: (err, perm) = ts3lib.getChannelVariable(schid, cid, ts3defines.ChannelProperties.CHANNEL_FLAG_SEMI_PERMANENT) if not perm: continue (err, name) = ts3lib.getChannelVariable(schid, cid, ts3defines.ChannelProperties.CHANNEL_NAME) if not self.chan.get("props", "name") in name: continue (err, parent) = ts3lib.getParentChannelOfChannel(schid, cid) if not parent == self.schids[schid]: continue return cid return 0 def createChannel(self, schid): ts3lib.setChannelVariableAsString(schid, 0, ts3defines.ChannelProperties.CHANNEL_NAME, self.chan.get("props", "name open")) ts3lib.setChannelVariableAsInt(schid, 0, ts3defines.ChannelProperties.CHANNEL_MAXCLIENTS, self.chan.getint("props", "maxclients")) ts3lib.setChannelVariableAsInt(schid, 0, ts3defines.ChannelProperties.CHANNEL_CODEC, self.chan.getint("props", "codec")) ts3lib.setChannelVariableAsInt(schid, 0, ts3defines.ChannelProperties.CHANNEL_CODEC_QUALITY, self.chan.getint("props", "codec_quality")) ts3lib.setChannelVariableAsString(schid, 0, ts3defines.ChannelProperties.CHANNEL_DESCRIPTION, self.description) ts3lib.setChannelVariableAsInt(schid, 0, ts3defines.ChannelProperties.CHANNEL_FLAG_SEMI_PERMANENT, 1) ts3lib.setChannelVariableAsInt(schid, 0, ts3defines.ChannelPropertiesRare.CHANNEL_FLAG_MAXCLIENTS_UNLIMITED, 0) ts3lib.setChannelVariableAsInt(schid, 0, ts3defines.ChannelPropertiesRare.CHANNEL_NEEDED_TALK_POWER, 1337) print(self.schids) print(self.schids[schid]) return ts3lib.flushChannelCreation(schid, self.schids[schid]) self.waitforchannel = True def onNewChannelCreatedEvent(self, schid, cid, channelParentID, invokerID, invokerName, invokerUniqueIdentifier): if not self.waitforchannel: return mycid = ts3lib.getChannelIDFromChannelNames(schid, self.cfg.get("general", "mychan").split(",")) if not channelParentID == mycid: return self.waitforchannel = False self.supchan = cid for (key, val) in self.chan.items("permissions"): (err, id) = ts3lib.getPermissionIDByName(schid, key) self.perm = (id, key, ts3lib.createReturnCode()) ts3lib.requestChannelAddPerm(schid, cid, [id], [int(val)]) # self.checkChannel(schid) def onServerPermissionErrorEvent(self, schid, errorMessage, error, returnCode, failedPermissionID): print(returnCode, self.perm[2]) if returnCode != self.perm[2]: return perm = self.perm ts3lib.printMessage(schid, "{}: Error setting permission [{}] #{} ({}): {} ({})".format(self.name, failedPermissionID, perm[0],perm[1],error,errorMessage), ts3defines.PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) self.perm = (0,"","") def checkChannel(self, schid): (err, clients) = ts3lib.getChannelClientList(schid, self.supchan); clients = len(clients) (err, maxclients) = ts3lib.getChannelVariable(schid, self.supchan, ts3defines.ChannelProperties.CHANNEL_MAXCLIENTS) if clients < maxclients: ts3lib.setChannelVariableAsString(schid, self.supchan, ts3defines.ChannelProperties.CHANNEL_NAME,self.chan.get("props", "name open")) elif clients >= maxclients: ts3lib.setChannelVariableAsString(schid, self.supchan, ts3defines.ChannelProperties.CHANNEL_NAME, self.chan.get("props", "name in use")) else: return ts3lib.flushChannelUpdates(schid, self.supchan) def onClientSelfVariableUpdateEvent(self, schid, flag, oldValue, newValue) : if not self.schids or len(self.schids) < 1 or schid != self.schids[0]: return if flag != ts3defines.ClientPropertiesRare.CLIENT_AWAY: return newValue = int(newValue) if newValue == ts3defines.AwayStatus.AWAY_ZZZ: ts3lib.setChannelVariableAsInt(schid, self.supchan, ts3defines.ChannelProperties.CHANNEL_MAXCLIENTS, 0) ts3lib.setChannelVariableAsString(schid, self.supchan, ts3defines.ChannelProperties.CHANNEL_NAME, self.chan.get("props", "name closed")) ts3lib.flushChannelUpdates(schid, self.supchan) elif newValue == ts3defines.AwayStatus.AWAY_NONE: ts3lib.setChannelVariableAsInt(schid, self.supchan, ts3defines.ChannelProperties.CHANNEL_MAXCLIENTS, self.chan.getint("props", "maxclients")) ts3lib.setChannelVariableAsString(schid, self.supchan, ts3defines.ChannelProperties.CHANNEL_NAME, self.chan.get("props", "name open")) ts3lib.flushChannelUpdates(schid, self.supchan) # self.checkChannel(schid) def onClientMoveEvent(self, schid, clid, oldChannelID, newChannelID, visibility, moveMessage): if not self.schids or len(self.schids) < 1 or schid != self.schids[0]: return if not self.supchan in [newChannelID, oldChannelID]: return (err, ownID) = ts3lib.getClientID(schid) (err, ownCID) = ts3lib.getChannelOfClient(schid, ownID) mycid = ts3lib.getChannelIDFromChannelNames(schid, self.cfg.get("general", "mychan").split(",")) (err, clients) = ts3lib.getChannelClientList(schid, mycid); clients = len(clients) if ownCID == mycid and clients == 1 and newChannelID == self.supchan: ts3lib.requestClientMove(schid, clid, mycid, "") else: self.checkChannel(schid) def onClientMoveMovedEvent(self, schid, clid, oldChannelID, newChannelID, visibility, moverID, moverName, moverUniqueIdentifier, moveMessage): if not self.schids or len(self.schids) < 1 or schid != self.schids[0]: return if self.supchan in [newChannelID, oldChannelID]: self.checkChannel(schid) def onClientKickFromChannelEvent(self, schid, clid, oldChannelID, newChannelID, visibility, kickerID, kickerName, kickerUniqueIdentifier, kickMessage): if not self.schids or len(self.schids) < 1 or schid != self.schids[0]: return if self.supchan == oldChannelID: self.checkChannel(schid) def onClientKickFromServerEvent(self, schid, clid, oldChannelID, newChannelID, visibility, kickerID, kickerName, kickerUniqueIdentifier, kickMessage): if not self.schids or len(self.schids) < 1 or schid != self.schids[0]: return if self.supchan == oldChannelID: self.checkChannel(schid) def onClientBanFromServerEvent(self, schid, clid, oldChannelID, newChannelID, visibility, kickerID, kickerName, kickerUniqueIdentifier, time, kickMessage): if not self.schids or len(self.schids) < 1 or schid != self.schids[0]: return if self.supchan == oldChannelID: self.checkChannel(schid)
class shittyExploits(ts3plugin): path = getScriptPath(__name__) name = "Shitty Exploits" try: apiVersion = getCurrentApiVersion() except: apiVersion = 21 requestAutoload = False version = "1.0" author = "Bluscream" description = "" offersConfigure = False commandKeyword = "" infoTitle = None # "[b]Shitty Exploits[/b]:" hotkeys = [] menuItems = [ (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CHANNEL, 0, "Reconnect here", "scripts/%s/refresh.svg" % __name__), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CHANNEL, 1, "Reconnect with TP", "scripts/%s/refresh.svg"%__name__), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CHANNEL, 2, "Reconnect with Commander", "scripts/%s/refresh.svg"%__name__), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CHANNEL, 3, "Reconnect with Recording", "scripts/%s/refresh.svg"%__name__), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CHANNEL, 4, "Reconnect with All", "scripts/%s/refresh.svg"%__name__), ] ini = "" cfg = {} def __init__(self): self.ini = "%s/shittyExploits/config.ini" % ts3lib.getPluginPath() self.cfg = loadCfg(self.ini) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def onMenuItemEvent(self, schid, atype, mID, selectedItemID): # self.cfg["client_is_talker"] = 1 if mID in [1,4] else 0 # self.cfg["client_is_channel_commander"] = 1 if mID in [2,4] else 0 # self.cfg["client_is_recording"] = 1 if mID in [3,4] else 0 # saveCfg(self.ini, self.cfg) # print(self.cfg) self.reconnect(schid, selectedItemID) def infoData(self, schid, id, atype): if atype != ts3defines.PluginItemType.PLUGIN_CHANNEL: return None with open(self.ini, encoding="utf-8") as f: return [line.rstrip('\n') for line in f.readlines()] def reconnect(self, schid=0, cid=0): if not schid: schid = ts3lib.getCurrentServerConnectionHandlerID() err, host, port, pw = ts3lib.getServerConnectInfo(schid) address = host if not "." in host else "{}:{}".format(host, port) # ts3lib.stopConnection(schid, "") err, nickname = ts3lib.getClientSelfVariable( schid, ts3defines.ClientProperties.CLIENT_NICKNAME) err, nickname_phonetic = ts3lib.getClientSelfVariable( schid, ts3defines.ClientPropertiesRare.CLIENT_NICKNAME_PHONETIC) err, uid = ts3lib.getClientSelfVariable( schid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) cpw = "" if not cid: err, cid = ts3lib.getClientSelfVariable( schid, ts3defines.ClientProperties.CLIENT_DEFAULT_CHANNEL) err, cpw = ts3lib.getClientSelfVariable( schid, ts3defines.ClientProperties.CLIENT_DEFAULT_CHANNEL_PASSWORD) else: (err, cid, cpw) = ts3lib.getChannelConnectInfo(schid, cid) err, default_token = ts3lib.getClientSelfVariable( schid, ts3defines.ClientPropertiesRare.CLIENT_DEFAULT_TOKEN) args = [ ts3defines.PluginConnectTab. PLUGIN_CONNECT_TAB_CURRENT, # connectTab: int, address, # serverLabel: Union[str, unicode], address, # serverAddress: Union[str, unicode], pw, # serverPassword: Union[str, unicode], nickname, # nickname: Union[str, unicode], cid, # channel: Union[str, unicode], cpw if cpw else "123", # channelPassword: Union[str, unicode] "", # captureProfile: Union[str, unicode], "", # playbackProfile: Union[str, unicode] "", # hotkeyProfile: Union[str, unicode], "Default Sound Pack (Female)", # soundPack uid, # userIdentity: Union[str, unicode], default_token, # oneTimeKey: Union[str, unicode], nickname_phonetic, # phoneticName: Union[str, unicode] ] print("ts3lib.guiConnect({})".format("\", \"".join( str(x) for x in args))) ts3lib.guiConnect(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13])
class quickMod(ts3plugin): path = getScriptPath(__name__) name = "Quick Moderation" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 22 requestAutoload = True version = "1.0" author = "Bluscream" description = "Allows you to set hotkeys for quick moderation (ban/restrict/remove tp)" offersConfigure = False commandKeyword = "qm" infoTitle = None menuItems = [] hotkeys = [ ("restrict_last_joined_server", "Restrict the last user that joined your server"), ("restrict_last_joined_channel", "Restrict the last user that joined your channel"), ("ban_last_joined_server", "Bans the last user that joined your server"), ("ban_last_joined_channel", "Bans the last user that joined your channel"), ("revoke_last_talk_power", "Revoke talk power from the last user that got TP in your channel"), ("restrict_last_joined_channel_from_local_channels", "Give the last user that joined your channel a cgid and sgid in certain channels" ), ("last_joined_channel_to_customBan", "Gives the last user that joined your channel to the customBan dialog" ), ("last_joined_server_to_customBan", "Gives the last user that joined your server to the customBan dialog" ), ("selected_to_customBan", "Gives the selected user to the customBan dialog"), ("join_selected_channel_pw", "Joins the selected channel (Bypasses passwords)"), ("rejoin_last_channel_pw", "Rejoins the last channel you left (Bypasses passwords)") ] ini = "%s/config.ini" % path cfg = ConfigParser() cfg["ban"] = { "duration": "2678400", "reason": "Ban Evading / Bannumgehung", "poke": "[color=red][b]You were banned from the server!", "name duration ": 120 } cfg["restrict"] = {"sgids": "", "poke": ""} cfg["restrict local"] = {"cids": "", "sgids": "", "cgid": "", "poke": ""} moveBeforeBan = 2 sgids = [] lastchans = {} last_joined_server = 0 last_joined_channel = 0 last_talk_power = 0 requested = 0 requestedIP = 0 retcode = "" customBan = None def __init__(self): self.app = QApplication.instance() loadCfg(self.ini, self.cfg) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def stop(self): pass # saveCfg(self.ini, self.cfg) def processCommand(self, schid, keyword): self.onHotkeyOrCommandEvent(keyword, schid) def onHotkeyEvent(self, keyword): self.onHotkeyOrCommandEvent(keyword) def onHotkeyOrCommandEvent(self, keyword, schid=0): try: if not schid: schid = ts3lib.getCurrentServerConnectionHandlerID() if keyword == "test": msg = [ "moveBeforeBan", self.moveBeforeBan, "sgids", self.sgids, "lastchans", self.lastchans, "last_joined_server", self.last_joined_server, "last_joined_channel", self.last_joined_channel, "last_talk_power", self.last_talk_power, "requested", self.requested, "requestedIP", self.requestedIP, "retcode", self.retcode ] print(msg) ts3lib.printMessageToCurrentTab(' '.join(str(x) for x in msg)) elif keyword == "restrict_last_joined_server": self.requested = self.last_joined_server msg = self.cfg.get("restrict", "poke") if msg: ts3lib.requestClientPoke(schid, self.requested, msg) ts3lib.requestClientVariables(schid, self.last_joined_server) # self.restrictClient(schid, self.last_joined_server) elif keyword == "restrict_last_joined_channel": self.requested = self.last_joined_channel msg = self.cfg.get("restrict", "poke") if msg: ts3lib.requestClientPoke(schid, self.requested, msg) ts3lib.requestClientVariables(schid, self.last_joined_channel) # self.restrictClient(schid, self.last_joined_channel) elif keyword == "ban_last_joined_server": msg = self.cfg.get("ban", "poke") if msg: ts3lib.requestClientPoke(schid, self.last_joined_server, msg) self.banClient(schid, self.last_joined_server) elif keyword == "ban_last_joined_channel": msg = self.cfg.get("ban", "poke") if msg: ts3lib.requestClientPoke(schid, self.last_joined_channel, msg) self.banClient(schid, self.last_joined_channel) elif keyword == "revoke_last_talk_power_channel": self.revokeTalkPower(schid, self.last_talk_power) elif keyword == "restrict_last_joined_channel_from_local_channels": self.restrictForeigners(schid, self.last_joined_channel) elif keyword == "last_joined_channel_to_customBan": self.toCustomBan(schid, self.last_joined_channel) elif keyword == "last_joined_server_to_customBan": self.toCustomBan(schid, self.last_joined_server) elif keyword == "selected_to_customBan": window = self.app.activeWindow() if window is None or not window.className() == "MainWindow": return selected = widget("ServerTreeView", self.app).currentIndex() if not selected: return name = selected.data() item = getIDByName(name, schid) if item[1] != ServerTreeItemType.CLIENT: ts3lib.playWaveFile(schid, path.join(self.path, "error.wav")) ts3lib.printMessageToCurrentTab( "{}: [color=red]No client with name[/color] {} [color=red]found![/color]" .format(self.name, name)) return self.toCustomBan(schid, item[0]) elif keyword == "join_selected_channel_pw": window = self.app.activeWindow() if window is None or not window.className() == "MainWindow": return selected = widget("ServerTreeView", self.app).currentIndex() if not selected: return name = selected.data() item = getIDByName(name, schid) if item[1] != ServerTreeItemType.CHANNEL: return (err, clid) = ts3lib.getClientID(schid) (err, cid) = ts3lib.getChannelOfClient(schid, clid) if cid == item[0]: return pw = getChannelPassword(schid, item[0], calculate=True) if not pw: return # ts3lib.printMessageToCurrentTab("{} > Joining {} (pw: {})".format(self.name, name, pw)) ts3lib.requestClientMove(schid, clid, item[0], pw) elif keyword == "rejoin_last_channel_pw": (err, clid) = ts3lib.getClientID(schid) (err, cid) = ts3lib.getChannelOfClient(schid, clid) tcid = self.lastchans[schid] if cid == tcid: return pw = getChannelPassword(schid, tcid, calculate=True) # (err, name) = ts3lib.getChannelVariable(schid, tcid, ts3defines.ChannelProperties.CHANNEL_NAME) # ts3lib.printMessageToCurrentTab("{} > Rejoining {} (pw: {})".format(self.name, name, pw)) ts3lib.requestClientMove(schid, clid, tcid, pw if pw else "123") except: print("error") ts3lib.logMessage(format_exc(), ts3defines.LogLevel.LogLevel_ERROR, "pyTSon", 0) return True def toCustomBan(self, schid, clid): active = PluginHost.active if not "Custom Ban" in active: ts3lib.printMessageToCurrentTab("%s: Customban plugin not active" % self.name) return active["Custom Ban"].onMenuItemEvent( schid, ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CLIENT, 0, clid) def banClient(self, schid, clid): (err, uid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if self.moveBeforeBan: ts3lib.requestClientMove(schid, clid, self.moveBeforeBan, "") if not ip: self.requestedIP = clid ts3lib.requestConnectionInfo(schid, clid) else: self.banIP(schid, ip) self.banUID(schid, uid) if self.cfg.getint("ban", "duration") != 0: (err, name) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_NICKNAME) self.banName(schid, clid, name) def onConnectionInfoEvent(self, schid, clid): if clid == self.requestedIP: self.requestedIP = 0 (err, uid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) self.banIP(schid, ip) self.banUID(schid, uid) if self.cfg.getint("ban", "duration") != 0: (err, name) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_NICKNAME) self.banName(schid, clid, name) def onUpdateClientEvent(self, schid, clid, invokerID, invokerName, invokerUniqueIdentifier): (err, ownID) = ts3lib.getClientID(schid) (err, cid) = ts3lib.getChannelOfClient(schid, clid) (err, ownCID) = ts3lib.getChannelOfClient(schid, ownID) (err, talker) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_IS_TALKER) if cid == ownCID and talker: self.last_talk_power = clid if clid == self.requested: self.requested = 0 if talker == 1: self.revokeTalkPower(schid, clid, True) # else: self.revokeTalkPower(schid, clid, False) (err, cldbid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_DATABASE_ID) (err, sgids) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_SERVERGROUPS) loc_sgids = intList(self.cfg.get("restrict", "sgids")) if set(loc_sgids).issubset(sgids): for sgid in loc_sgids: ts3lib.requestServerGroupDelClient(schid, sgid, cldbid) else: for sgid in loc_sgids: ts3lib.requestServerGroupAddClient(schid, sgid, cldbid) def revokeTalkPower(self, schid, clid, revoke=True): self.retcode = ts3lib.createReturnCode() ts3lib.requestClientSetIsTalker(schid, clid, not revoke, self.retcode) def restrictForeigners(self, schid, clid): (err, cldbid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_DATABASE_ID) (err, sgids) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_SERVERGROUPS) loc_sgids = intList(self.cfg.get("restrict local", "sgids")) loc_cids = intList(self.cfg.get("restrict local", "cids")) if sgids and set(loc_sgids).issubset(sgids): for sgid in loc_sgids: ts3lib.requestServerGroupDelClient(schid, sgid, cldbid) (err, dcgid) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerPropertiesRare. VIRTUALSERVER_DEFAULT_CHANNEL_GROUP) ts3lib.requestSetClientChannelGroup(schid, [dcgid] * len(loc_cids), loc_cids, [cldbid] * len(loc_cids)) return for sgid in loc_sgids: ts3lib.requestServerGroupAddClient(schid, sgid, cldbid) ts3lib.requestSetClientChannelGroup( schid, [self.cfg.getint("restrict local", "cgid")] * len(loc_cids), loc_cids, [cldbid] * len(loc_cids)) msg = self.cfg.get("restrict local", "poke") if msg: ts3lib.requestClientPoke(schid, self.last_joined_channel, msg) # ts3lib.requestClientKickFromChannel(schid, clid, msg) def banReason(self): reason = self.cfg.get("ban", "reason") if reason[0].isdigit(): reason = "§" + reason return reason def banUID(self, schid, uid): ts3lib.banadd(schid, "", "", uid, self.cfg.getint("ban", "duration"), self.banReason()) def banIP(self, schid, ip): if not ip: return active = PluginHost.active if "Custom Ban" in active: whitelist = active["Custom Ban"].whitelist if len(whitelist) > 1: if ip in whitelist: ts3lib.printMessageToCurrentTab( "{}: [color=red]Not banning whitelisted IP [b]{}". format(self.name, ip)) return else: ts3lib.printMessageToCurrentTab( "{}: \"Custom Ban\"'s IP Whitelist faulty, please check!". format(self.name)) return ts3lib.banadd(schid, ip, "", "", 0, self.banReason()) def banName(self, schid, target, name): name_in_use = False (err, clids) = ts3lib.getClientList(schid) for clid in clids: if clid == target: continue (err, _name) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_NICKNAME) if name in _name: name_in_use = True if not name_in_use: name = ".*{}.*".format(name) print("inuse:", name_in_use, "name:", name) ts3lib.banadd(schid, "", name, "", self.cfg.getint("ban", "name duration"), self.banReason()) def onClientMoveEvent(self, schid, clid, oldChannelID, newChannelID, visibility, moveMessage): (err, ownID) = ts3lib.getClientID(schid) if clid == ownID: self.lastchans[schid] = oldChannelID if schid != ts3lib.getCurrentServerConnectionHandlerID(): return if clid == ownID: return (err, sgids) = ts3lib.getClientVariableAsString( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_SERVERGROUPS) if sgids is not None and self.sgids: sgids = intList(sgids) if not any(x in sgids for x in self.sgids): return if oldChannelID == 0: self.last_joined_server = clid (err, ownCID) = ts3lib.getChannelOfClient(schid, ownID) if newChannelID == ownCID: self.last_joined_channel = clid def onServerErrorEvent(self, schid, errorMessage, error, returnCode, extraMessage): if returnCode == self.retcode: return True
class antiSpam(ts3plugin): path = getScriptPath(__name__) name = "Anti Spam" apiVersion = 22 try: apiVersion = getCurrentApiVersion() except: apiVersion = 21 version = "1.0" author = "Bluscream" description = "" requestAutoload = False offersConfigure = False commandKeyword = "" infoTitle = None hotkeys = [] menuItems = [] ini = "%s/config.ini" % path cfg = ConfigParser({ "messages": { "block similar messages": "True", "force show ignored messages": "False", "block messages longer then": str(ts3defines.TS3_MAX_SIZE_TEXTMESSAGE), "whitespace": "strip", # block "block messages sent inbetween": "1000", "apply to": "1,2,3" # ",".join([ts3defines.TextMessageTargetMode.TextMessageTarget_CLIENT,ts3defines.TextMessageTargetMode.TextMessageTarget_CHANNEL,ts3defines.TextMessageTargetMode.TextMessageTarget_SERVER]) } }) tabs = {} def __init__(self): loadCfg(self.ini, self.cfg) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def stop(self): del self.tabs def onTextMessageEvent(self, schid, targetMode, toID, fromID, fromName, fromUniqueIdentifier, message, ffIgnored): if self.cfg.getboolean("messages", "force show ignored messages"): pass if self.cfg.getboolean("messages", "block similar messages"): pass def onClientPokeEvent(self, schid, fromClientID, pokerName, pokerUID, message, ffIgnored): pass def onClientMoveEvent(self, schid, clientID, oldChannelID, newChannelID, visibility, moveMessage): if newChannelID == 0: self.removeClient(schid, clientID) def onClientKickFromServerEvent(self, schid, clientID, oldChannelID, newChannelID, visibility, kickerID, kickerName, kickerUniqueIdentifier, kickMessage): self.removeClient(schid, clientID) def removeClient(self, schid, clid): if not schid in self.tabs: return if not clid in self.tabs[schid]: return del self.tabs[schid][clid] def addClient(self, schid, clid): if not schid in self.tabs: self.tabs[schid] = {} if not clid in self.tabs[schid]: self.tabs[schid][clid] = {}
class autoProxy(ts3plugin): path = getScriptPath(__name__) name = "Automatic Proxy" try: apiVersion = getCurrentApiVersion() except: apiVersion = 21 requestAutoload = False version = "1.2" author = "Bluscream" description = "Uses ts3.cloud's ts3proxy service to switch to a proxy on every connection." offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [ (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 0, "Toggle %s"%name, "scripts/%s/proxy.png"%__name__), (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 1, "Proxy whitelist", "scripts/%s/whitelist.png"%__name__) ] hotkeys = [] proxied = False nwmc = QNetworkAccessManager() nwmc_resolver = QNetworkAccessManager() request = QNetworkRequest(QUrl("https://www.ts3.cloud/ts3proxy")) payload = "input={host}:{port}&proxy=" whitelist_ini = "%s/whitelist.txt" % path whitelist = [] backup = {"address": "127.0.0.1:9987", "nickname": "", "phonetic": "", "token": "", "c": "AFK", "cpw": "123", "pw": "123"} enabled = True def __init__(self): content = [] if not path.exists(self.whitelist_ini): with open(self.whitelist_ini, 'w'): pass with open(self.whitelist_ini, encoding="utf-8") as f: content = f.readlines() self.whitelist = [x.strip() for x in content] self.nwmc.connect("finished(QNetworkReply*)", self.reply) self.nwmc_resolver.connect("finished(QNetworkReply*)", self.resolveReply) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded.".format(timestamp(), self.name, self.author)) def onMenuItemEvent(self, schid, atype, menuItemID, selectedItemID): if atype != ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL: return if menuItemID == 0: self.enabled = not self.enabled if self.enabled: ts3lib.printMessageToCurrentTab("{} > [color=green]Enabled!".format(self.name)) else: ts3lib.printMessageToCurrentTab("{} > [color=red]Disabled!".format(self.name)) elif menuItemID == 1: err, host, port, pw = ts3lib.getServerConnectInfo(schid) host = inputBox(self.name, "Server address:", host) if not host: msgBox("Nothing to add!", title=self.name); return if host in self.whitelist: self.whitelist.remove(host) ts3lib.printMessageToCurrentTab("{} > Removed {} from whitelist!".format(self.name,host)) else: self.whitelist.append(host.lower()) ts3lib.printMessageToCurrentTab("{} > Added {} to whitelist!".format(self.name,host)) with open(self.whitelist_ini, "a") as myfile: myfile.write('\n{0}'.format(host)) def onConnectStatusChangeEvent(self, schid, newStatus, errorNumber): if not self.enabled: return if newStatus != ts3defines.ConnectStatus.STATUS_CONNECTING: return if self.proxied: self.proxied = False; return err, host, port, pw = ts3lib.getServerConnectInfo(schid) if host.lower() in self.whitelist: ts3lib.printMessageToCurrentTab("[color=green]%s is whitelisted, not using proxy!" % host); return ip = QHostAddress(host) if not ip.isNull(): if ip.isLoopback(): ts3lib.printMessageToCurrentTab("[color=green]%s is Loopback, not using proxy!" % host); return elif ip.isMulticast(): ts3lib.printMessageToCurrentTab("[color=green]%s is Multicast, not using proxy!" % host); return is_nickname = False if not "." in host: ts3lib.printMessageToCurrentTab("[color=orange]%s is a server nickname, resolving..." % host) self.backup["address"] = host is_nickname = True if not is_nickname: self.backup["address"] = "{}:{}".format(host,port) ts3lib.printMessageToCurrentTab("[color=red]Not proxied on %s, disconnecting!"%self.backup["address"]) ts3lib.stopConnection(schid, "switching to proxy") if pw: self.backup["pw"] = pw err, nickname = ts3lib.getClientSelfVariable(schid, ts3defines.ClientProperties.CLIENT_NICKNAME) if not err and nickname: self.backup["nickname"] = nickname err, nickname_phonetic = ts3lib.getClientSelfVariable(schid, ts3defines.ClientPropertiesRare.CLIENT_NICKNAME_PHONETIC) if not err and nickname_phonetic: self.backup["phonetic"] = nickname_phonetic err, c = ts3lib.getClientSelfVariable(schid, ts3defines.ClientProperties.CLIENT_DEFAULT_CHANNEL) if not err and c: self.backup["c"] = c err, cpw = ts3lib.getClientSelfVariable(schid, ts3defines.ClientProperties.CLIENT_DEFAULT_CHANNEL_PASSWORD) if not err and cpw: self.backup["cpw"] = cpw err, default_token = ts3lib.getClientSelfVariable(schid, ts3defines.ClientPropertiesRare.CLIENT_DEFAULT_TOKEN) if not err and default_token: self.backup["token"] = default_token if is_nickname: self.nwmc_resolver.get(QNetworkRequest(QUrl("https://named.myteamspeak.com/lookup?name=%s"%host))) return self.proxy(host, port) def proxy(self, host, port): payload = self.payload.format(host=host,port=port) self.nwmc.post(self.request, payload) def reply(self, reply): page = reply.readAll().data().decode('utf-8') soup = BeautifulSoup(page, features="html.parser") div_alert = soup.find("div", {"class": "alert alert-success alert-dismissable"}) proxy_adress = div_alert.find("center").find("b").text ts3lib.printMessageToCurrentTab("[color=green]Connecting to proxy %s"%proxy_adress) self.proxied = True ts3lib.guiConnect(ts3defines.PluginConnectTab.PLUGIN_CONNECT_TAB_CURRENT, self.backup["address"], # Name proxy_adress, # Address self.backup["pw"], # Server Password self.backup["nickname"], # Nickname self.backup["c"], # Channel Path self.backup["cpw"], # Channel Password "", "", "", "", "", self.backup["token"], # Privilege Key self.backup["phonetic"] # Phonetic Nickname ) def resolveReply(self, reply): resolved = reply.readAll().data().decode('utf-8').strip() ts3lib.printMessageToCurrentTab("[color=green]Resolved server nickname %s to %s" % (self.backup["address"], resolved)) resolved = resolved.split(":") self.proxy(resolved[0], resolved[1] if len(resolved) > 1 else 9987)
class sessionRestore(ts3plugin): path = getScriptPath(__name__) name = "Session Restore" apiVersion = 22 requestAutoload = False version = "1.0" author = "Bluscream" description = "Restores your last session on startup" offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [] hotkeys = [] timer = QTimer() delay = 500 increase = 2000 ts3host = None tabs = {} _delay = delay _tabs = {} _timers = [] backup_file = os.path.join(path, "session.json") first = True def __init__(self): if "aaa_ts3Ext" in PluginHost.active: ts3ext = PluginHost.active["aaa_ts3Ext"] self.tabs = ts3ext.tabs ts3lib.logMessage("{}: Dependency loaded".format(self.name), LogLevel.LogLevel_WARNING, "pyTSon", 0) log( self, LogLevel.LogLevel_DEBUG, "[color=orange]{name}[/color] Plugin for pyTSon by [url=https://github.com/{author}]{author}[/url] loaded." .format(name=self.name, author=self.author), 0) else: retry = 1000 self.timer.singleShot(retry, self.__init__) ts3lib.logMessage( "{}: Dependency not yet loaded, retrying in {} second(s)!". format(self.name, retry / 1000), LogLevel.LogLevel_WARNING, "pyTSon", 0) def stop(self): if hasattr(self, "timer"): if self.timer.isActive(): self.timer.stop() def saveTabs(self): tabs = {} # Todo: OrderedDict for tab in self.tabs: if self.tabs[tab][ "status"] == ConnectStatus.STATUS_CONNECTION_ESTABLISHED: tabs[tab] = self.tabs[tab] if not len(tabs): return with open(self.backup_file, 'w') as outfile: dump(tabs, outfile) def restoreTabs(self): try: err, schids = ts3lib.getServerConnectionHandlerList() if err != ERROR_ok: return if len(schids) > 1: return for schid in schids: (err, status) = ts3lib.getConnectionStatus(schid) if err != ERROR_ok: return if status != ConnectStatus.STATUS_DISCONNECTED: return self._tabs = {} self._timers = [] with open(self.backup_file) as f: self._tabs = load(f) i = 0 self._delay = self.delay for tab in self._tabs: i += 1 # if self._tabs[tab]["status"] == ConnectStatus.STATUS_CONNECTION_ESTABLISHED: timer = QTimer() self._timers.append(timer) timer.singleShot(self._delay, self.restoreTab) # self.restoreTab(tab) self._delay += self.increase except: ts3lib.logMessage(format_exc(), LogLevel.LogLevel_ERROR, "pyTSon", 0) def restoreTab(self, tab=None): try: if not tab: self._timers.pop(0) schid, tab = self._tabs.popitem() args = [ PluginConnectTab.PLUGIN_CONNECT_TAB_NEW_IF_CURRENT_CONNECTED if self.first else PluginConnectTab.PLUGIN_CONNECT_TAB_NEW, # connectTab: int, tab["name"], # serverLabel: Union[str, unicode], tab["address"], # serverAddress: Union[str, unicode], tab["pw"], # serverPassword: Union[str, unicode], tab["nick"], # nickname: Union[str, unicode], tab["cpath"], # channel: Union[str, unicode], tab["cpw"], # channelPassword: Union[str, unicode] "", # captureProfile: Union[str, unicode], "", # playbackProfile: Union[str, unicode] "", # hotkeyProfile: Union[str, unicode], "Default Sound Pack (Female)", # soundPack tab["uid"], # userIdentity: Union[str, unicode], tab["token"], # oneTimeKey: Union[str, unicode], tab["nick_phonetic"] # phoneticName: Union[str, unicode] ] if self.first: self.first = False print("ts3lib.guiConnect({})".format("\", \"".join( str(x) for x in args))) err, schid = ts3lib.guiConnect(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13]) print("TAB: ", tab) ts3lib.setClientSelfVariableAsInt( schid, ClientProperties.CLIENT_INPUT_MUTED, tab["input_muted"]) ts3lib.setClientSelfVariableAsInt( schid, ClientProperties.CLIENT_OUTPUT_MUTED, int(tab["output_muted"])) ts3lib.requestChannelSubscribeAll(schid) except: ts3lib.logMessage(format_exc(), LogLevel.LogLevel_ERROR, "pyTSon", 0) def menuCreated(self): if not self.first: return self.timer.timeout.connect(self.saveTabs) self.timer.setTimerType(2) self.timer.start(5000) self.restoreTabs()
class dontHide(ts3plugin): path = getScriptPath(__name__) name = "Don't Hide" try: apiVersion = getCurrentApiVersion() except: apiVersion = 22 requestAutoload = False version = "1.0" author = "Bluscream" description = "Shows clients that hide." offersConfigure = False commandKeyword = "" infoTitle = " " menuItems = [] hotkeys = [] timer = QTimer() ts3host = None schid = None def __init__(self): if "aaa_ts3Ext" in PluginHost.active: ts3ext = PluginHost.active["aaa_ts3Ext"] self.ts3host = ts3ext.ts3host ts3lib.logMessage("{}: Dependency loaded".format(self.name), ts3defines.LogLevel.LogLevel_WARNING, "pyTSon", 0) else: retry = 1000 self.timer.singleShot(retry, self.__init__) ts3lib.logMessage( "{}: Dependency not yet loaded, retrying in {} second(s)!". format(self.name, retry / 1000), ts3defines.LogLevel.LogLevel_WARNING, "pyTSon", 0) return if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def stop(self): if hasattr(self, "timer"): if self.timer.isActive(): self.timer.stop() def onConnectStatusChangeEvent(self, schid, newStatus, errorNumber): if newStatus != ts3defines.ConnectStatus.STATUS_CONNECTION_ESTABLISHED: return self.schid = schid self.timer.singleShot(1000, self.printHidden) def printHidden(self): counts = self.getClientCounts(self.schid) if counts["hidden"]["total"] > 0: ts3lib.printMessage( self.schid, "[color=orange][b]{}[/b] users are hidden on this server!". format(counts["hidden"]["total"]), ts3defines.PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) def getClientCounts(self, schid): ret = {"total": {}, "visible": {}, "hidden": {}} visible = self.ts3host.getServer( schid).users # err, visible = ts3lib.getClientList(schid) ret["visible"]["users"] = 0 ret["visible"]["queries"] = 0 for user in visible: (err, ctype) = ts3lib.getClientVariable( schid, user.clientID, ts3defines.ClientPropertiesRare.CLIENT_TYPE) if ctype == ts3defines.ClientType.ClientType_NORMAL: ret["visible"]["users"] += 1 elif ctype == ts3defines.ClientType.ClientType_SERVERQUERY: ret["visible"]["queries"] += 1 ret["visible"]["total"] = ret["visible"]["users"] + ret["visible"][ "queries"] # len(visible) (err, ret["total"]["clients"]) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerProperties.VIRTUALSERVER_CLIENTS_ONLINE) (err, ret["total"]["queries"]) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerPropertiesRare. VIRTUALSERVER_QUERYCLIENTS_ONLINE) (err, ret["max"]) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerProperties.VIRTUALSERVER_MAXCLIENTS) ret["hidden"][ "total"] = ret["total"]["clients"] - ret["visible"]["total"] return ret def infoData(self, schid, aid, atype): if atype != ts3defines.PluginItemType.PLUGIN_SERVER: return counts = self.getClientCounts(schid) # if counts["hidden"]["total"] > 0: return [ "Shown Clients: %s" % counts["visible"]["users"], "Shown Queries: %s" % counts["visible"]["queries"], "Hidden: %s" % counts["hidden"]["total"] ] #, "{}".format(counts) # return None # ["clients:%s"%clients, "queries:%s"%queries, "max:%s"%max, "visible_users:%s"%visible_users, "visible_queries:%s"%visible_queries] def onClientMoveEvent(self, schid, clid, oldChannelID, newChannelID, visibility, moveMessage): if not newChannelID: return return if visibility == ts3defines.Visibility.LEAVE_VISIBILITY: cmd = "notifycliententerview" client = self.buildClient(schid, clid, oldChannelID, newChannelID) for k in client: if client[k] != "": cmd += " {}={}".format(k, client[k]) else: cmd += " {}".format(k) sendCommand(self.name, cmd, schid, False, True) def buildClient(self, schid, clid, oldChannelID, newChannelID): _client = self.ts3host.getUser(schid, clid) client = dict() client["reasonid"] = "0" client["cfid"] = oldChannelID client["ctid"] = newChannelID client["client_channel_group_id"] = _client.getChannelGroupId() (err, client["client_servergroups"]) = ts3lib.getClientVariableAsString( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_SERVERGROUPS) (err, client["client_channel_group_inherited_channel_id"] ) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare. CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID) client["client_input_muted"] = _client.isInputMuted client["client_output_muted"] = _client.isOutputMuted client["client_outputonly_muted"] = _client.isOutputOnlyMuted (err, client["client_input_hardware"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_INPUT_HARDWARE) (err, client["client_output_hardware"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_OUTPUT_HARDWARE) client["client_is_recording"] = _client.isRecording (err, client["client_type"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_TYPE) client["client_is_talker"] = _client.isTalker client["client_away"] = _client.isAway client["client_is_channel_commander"] = _client.isChannelCommander (err, client["client_is_priority_speaker"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_IS_PRIORITY_SPEAKER) client["clid"] = clid client["client_database_id"] = _client.databaseID client["client_talk_power"] = _client.talkPower (err, client["client_unread_messages"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_UNREAD_MESSAGES) (err, client["client_needed_serverquery_view_power"] ) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare. CLIENT_NEEDED_SERVERQUERY_VIEW_POWER) client["client_icon_id"] = _client.iconID client["client_unique_identifier"] = _client.uniqueIdentifier client["client_nickname"] = _client.name (err, client["client_meta_data"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_META_DATA) (err, client["client_away_message"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_AWAY_MESSAGE) (err, client["client_flag_avatar"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_FLAG_AVATAR) (err, client["client_talk_request"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_OUTPUT_HARDWARE) (err, client["client_talk_request_msg"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_TALK_REQUEST_MSG) client["client_description"] = _client.description (err, client["client_nickname_phonetic"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_NICKNAME_PHONETIC) (err, client["client_country"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_COUNTRY) (err, client["client_badges"]) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_BADGES) return client
class antiVPN(ts3plugin): path = getScriptPath(__name__) name = "Anti VPN" apiVersion = 22 requestAutoload = False version = "1.0" author = "Bluscream" description = "Kicks users with VPNs" offersConfigure = True commandKeyword = "" infoTitle = None menuItems = [] hotkeys = [] ini = "%s/config.ini" % path cfg = ConfigParser() cfg["general"] = { "cfgversion": "1", "enabled": "True", "api": "http://v2.api.iphub.info/ip/{ip}", "apikey": "Get yours at https://iphub.info/apiKey" } requested = {} def __init__(self): loadCfg(self.ini, self.cfg) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def onClientMoveEvent(self, schid, clid, oldChannelID, newChannelID, visibility, moveMessage): if not self.cfg.getboolean("general", "enabled"): return if oldChannelID != 0: return (error, _type) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_TYPE) if _type == ts3defines.ClientType.ClientType_SERVERQUERY: return self.requested[schid] = [(schid, clid, "")] ts3lib.requestConnectionInfo(schid, clid) def onConnectionInfoEvent(self, schid, clientID): if not self.requested == clientID: return (error, ip) = ts3lib.getConnectionVariableAsString( schid, clientID, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if error == ts3defines.ERROR_ok: self.ip = ip self.nwm = QNetworkAccessManager() self.nwm.connect("finished(QNetworkReply*)", self.onMainReply) self.nwm.get( QNetworkRequest( QUrl(self.cfg['api']['main'].replace("{ip}", ip)))) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( self.cfg['api']['main'].replace("{ip}", ip)) else: (e, msg) = ts3lib.getErrorMessage(error) ts3lib.printMessageToCurrentTab( "[[color=orange]WARNING[/color]] [color=red]ISPValidator could not resolve the IP for '%s' (Reason: %s)" % (clientURL(schid, clientID), msg)) def onMainReply(self, reply): if reply.error() == QNetworkReply.NoError: try: isp = reply.readAll().data().decode('utf-8') if isp.startswith('AS'): isp = isp.split(" ", 1)[1] if not isp or isp == "" or isp == "undefined": ts3lib.printMessageToCurrentTab( "[[color=orange]WARNING[/color]] [color=red]ISPValidator could not resolve the ISP for '%s' (Reason: %s) Falling back to %s" % (clientURL(self.schid, self.requested), format_exc(), self.cfg['api']['fallback'].replace("{ip}", self.ip))) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( self.cfg['api']['fallback'].replace( "{ip}", self.ip)) self.nwb = QNetworkAccessManager() self.nwb.connect("finished(QNetworkReply*)", self.onFallbackReply) self.nwb.get( QNetworkRequest( QUrl(self.cfg['api']['fallback'].replace( "{ip}", self.ip)))) return if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "%s's ISP: %s" % (clientURL(self.schid, self.requested), isp)) _match = False for _isp in self.isps: if isp == _isp: _match = True if self.cfg.getboolean('general', 'whitelist') and not _match: if self.cfg.getboolean('main', 'kickonly'): ts3lib.requestClientKickFromServer( self.schid, self.requested, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 else: ts3lib.banclient( self.schid, self.requested, 60, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 elif not self.cfg.getboolean('general', 'whitelist') and _match: if self.cfg.getboolean('main', 'kickonly'): ts3lib.requestClientKickFromServer( self.schid, self.requested, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 else: ts3lib.banclient( self.schid, self.requested, 60, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 except: try: ts3lib.printMessageToCurrentTab( "[[color=orange]WARNING[/color]] [color=red]ISPValidator could not resolve the ISP for '%s' (Reason: %s) Falling back to %s" % (clientURL(self.schid, self.requested), format_exc(), self.cfg['api']['fallback'].replace("{ip}", self.ip))) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( self.cfg['api']['fallback'].replace( "{ip}", self.ip)) self.nwb = QNetworkAccessManager() self.nwb.connect("finished(QNetworkReply*)", self.onFallbackReply) self.nwb.get( QNetworkRequest( QUrl(self.cfg['api']['fallback'].replace( "{ip}", self.ip)))) except: pass else: ts3lib.printMessageToCurrentTab( "[[color=orange]WARNING[/color]] [color=red]ISPValidator could not resolve the ISP for '%s' (Reason: %s) Falling back to %s" % (clientURL(self.schid, self.requested), reply.errorString(), self.cfg['api']['fallback'].replace("{ip}", self.ip))) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( self.cfg['api']['fallback'].replace("{ip}", self.ip)) self.nwb = QNetworkAccessManager() self.nwb.connect("finished(QNetworkReply*)", self.onFallbackReply) self.nwb.get( QNetworkRequest( QUrl(self.cfg['api']['fallback'].replace("{ip}", self.ip)))) reply.deleteLater() def onFallbackReply(self, reply): if reply.error() == QNetworkReply.NoError: try: isp = reply.readAll().data().decode('utf-8') if isp.startswith('AS'): isp = isp.split(" ", 1)[1] if not isp or isp == "" or isp == "undefined": ts3lib.printMessageToCurrentTab( "[[color=orange]WARNING[/color]] [color=red]ISPValidator could not resolve the ISP for '%s' (Reason: %s)" % (clientURL(self.schid, self.requested), format_exc())) if self.cfg.getboolean("failover", "enabled"): if self.cfg.getboolean('failover', 'kickonly'): ts3lib.requestClientKickFromServer( self.schid, self.requested, self.cfg['failover']['reason'].replace( '{isp}', isp)) else: ts3lib.banclient( self.schid, self.requested, int(self.cfg['failover']['bantime']), self.cfg['failover']['reason'].replace( '{isp}', isp)) self.requested = 0 reply.deleteLater() return if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "%s's ISP: %s" % (clientURL(self.schid, self.requested), isp)) _match = False for _isp in self.isps: if isp == _isp: _match = True if self.cfg.getboolean('general', 'whitelist') and not _match: if self.cfg.getboolean('main', 'kickonly'): ts3lib.requestClientKickFromServer( self.schid, self.requested, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 else: ts3lib.banclient( self.schid, self.requested, 60, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 elif not self.cfg.getboolean('general', 'whitelist') and _match: if self.cfg.getboolean('main', 'kickonly'): ts3lib.requestClientKickFromServer( self.schid, self.requested, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 else: ts3lib.banclient( self.schid, self.requested, 60, "%s is not a valid Internet Service Provider!" % isp) self.requested = 0 except: ts3lib.printMessageToCurrentTab( "[[color=orange]WARNING[/color]] [color=red]ISPValidator could not resolve the ISP for '%s' (Reason: %s)" % (clientURL(self.schid, self.requested), "")) if self.cfg.getboolean("failover", "enabled"): if self.cfg.getboolean('failover', 'kickonly'): ts3lib.requestClientKickFromServer( self.schid, self.requested, self.cfg['failover']['reason'].replace( '{isp}', isp)) else: ts3lib.banclient( self.schid, self.requested, int(self.cfg['failover']['bantime']), self.cfg['failover']['reason'].replace( '{isp}', isp)) else: ts3lib.printMessageToCurrentTab( "[[color=orange]WARNING[/color]] [color=red]ISPValidator could not resolve the ISP for '%s' (Reason: %s)" % (clientURL(self.schid, self.requested), reply.errorString())) if self.cfg.getboolean("failover", "enabled"): if self.cfg.getboolean('failover', 'kickonly'): ts3lib.requestClientKickFromServer( self.schid, self.requested, self.cfg['failover']['reason'].replace('{isp}', isp)) else: ts3lib.banclient( self.schid, self.requested, int(self.cfg['failover']['bantime']), self.cfg['failover']['reason'].replace('{isp}', isp)) self.requested = 0 reply.deleteLater()
class quickMod(ts3plugin): path = getScriptPath(__name__) name = "Quick Moderation" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 22 requestAutoload = True version = "1.0" author = "Bluscream" description = "Allows you to set hotkeys for quick moderation (ban/restrict/remove tp)" offersConfigure = False commandKeyword = "qm" infoTitle = None menuItems = [] hotkeys = [ ("restrict_last_joined_server", "Restrict the last user that joined your server"), ("restrict_last_joined_channel", "Restrict the last user that joined your channel"), ("ban_last_joined_server", "Bans the last user that joined your server"), ("ban_last_joined_channel", "Bans the last user that joined your channel"), ("revoke_last_talk_power", "Revoke talk power from the last user that got TP in your channel"), ("restrict_last_joined_channel_from_local_channels", "Give the last user that joined your channel a cgid and sgid in certain channels" ), ("last_joined_channel_to_customBan", "Gives the last user that joined your channel to the customBan dialog" ), ("last_joined_server_to_customBan", "Gives the last user that joined your server to the customBan dialog" ), ] last_joined_server = 0 last_joined_channel = 0 last_talk_power = 0 requested = 0 requestedIP = 0 retcode = "" customBan = None ini = "%s/config.ini" % path cfg = ConfigParser() cfg["ban"] = { "duration": "2678400", "reason": "Ban Evading / Bannumgehung", "poke": "[color=red][b]You we're banned from the server!" } cfg["restrict"] = { "sgids": "", "reason": "Ban Evading / Bannumgehung", "poke": "" } cfg["restrict local"] = {"cids": "", "sgids": "", "cgid": "", "poke": ""} moveBeforeBan = 26 def __init__(self): loadCfg(self.ini, self.cfg) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def stop(self): pass # saveCfg(self.ini, self.cfg) def processCommand(self, schid, keyword): self.onHotkeyOrCommandEvent(keyword, schid) def onHotkeyEvent(self, keyword): self.onHotkeyOrCommandEvent(keyword) def onHotkeyOrCommandEvent(self, keyword, schid=0): schid = ts3lib.getCurrentServerConnectionHandlerID() if keyword == "restrict_last_joined_server": self.requested = self.last_joined_server msg = self.cfg.get("restrict", "poke") if msg: ts3lib.requestClientPoke(schid, self.requested, msg) ts3lib.requestClientVariables(schid, self.last_joined_server) # self.restrictClient(schid, self.last_joined_server) elif keyword == "restrict_last_joined_channel": self.requested = self.last_joined_channel msg = self.cfg.get("restrict", "poke") if msg: ts3lib.requestClientPoke(schid, self.requested, msg) ts3lib.requestClientVariables(schid, self.last_joined_channel) # self.restrictClient(schid, self.last_joined_channel) elif keyword == "ban_last_joined_server": msg = self.cfg.get("ban", "poke") if msg: ts3lib.requestClientPoke(schid, self.last_joined_server, msg) self.banClient(schid, self.last_joined_server) elif keyword == "ban_last_joined_channel": msg = self.cfg.get("ban", "poke") if msg: ts3lib.requestClientPoke(schid, self.last_joined_channel, msg) self.banClient(schid, self.last_joined_channel) elif keyword == "revoke_last_talk_power_channel": self.revokeTalkPower(schid, self.last_talk_power) elif keyword == "restrict_last_joined_channel_from_local_channels": self.restrictForeigners(schid, self.last_joined_channel) elif keyword == "last_joined_channel_to_customBan": self.toCustomBan(schid, self.last_joined_channel) elif keyword == "last_joined_server_to_customBan": self.toCustomBan(schid, self.last_joined_server) def toCustomBan(self, schid, clid): active = PluginHost.active if not "Custom Ban" in active: return active["Custom Ban"].onMenuItemEvent( schid, ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CLIENT, 0, clid) def banClient(self, schid, clid): (err, uid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if self.moveBeforeBan: ts3lib.requestClientMove(schid, clid, self.moveBeforeBan, "") if not ip: self.requestedIP = clid ts3lib.requestConnectionInfo(schid, clid) else: self.banIP(schid, ip) self.banUID(schid, uid) def onConnectionInfoEvent(self, schid, clid): if clid == self.requestedIP: self.requestedIP = 0 (err, uid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) self.banIP(schid, ip) self.banUID(schid, uid) def onUpdateClientEvent(self, schid, clid, invokerID, invokerName, invokerUniqueIdentifier): (err, ownID) = ts3lib.getClientID(schid) (err, cid) = ts3lib.getChannelOfClient(schid, clid) (err, ownCID) = ts3lib.getChannelOfClient(schid, ownID) (err, talker) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_IS_TALKER) if cid == ownCID and talker: self.last_talk_power = clid if clid == self.requested: self.requested = 0 if talker == 1: self.revokeTalkPower(schid, clid, True) # else: self.revokeTalkPower(schid, clid, False) (err, cldbid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_DATABASE_ID) (err, sgids) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_SERVERGROUPS) loc_sgids = intList(self.cfg.get("restrict", "sgids")) if set(loc_sgids).issubset(sgids): for sgid in loc_sgids: ts3lib.requestServerGroupDelClient(schid, sgid, cldbid) else: for sgid in loc_sgids: ts3lib.requestServerGroupAddClient(schid, sgid, cldbid) def revokeTalkPower(self, schid, clid, revoke=True): self.retcode = ts3lib.createReturnCode() ts3lib.requestClientSetIsTalker(schid, clid, revoke, self.retcode) def restrictForeigners(self, schid, clid): (err, cldbid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_DATABASE_ID) (err, sgids) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientPropertiesRare.CLIENT_SERVERGROUPS) loc_sgids = intList(self.cfg.get("restrict local", "sgids")) loc_cids = intList(self.cfg.get("restrict local", "cids")) if sgids and set(loc_sgids).issubset(sgids): for sgid in loc_sgids: ts3lib.requestServerGroupDelClient(schid, sgid, cldbid) (err, dcgid) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerPropertiesRare. VIRTUALSERVER_DEFAULT_CHANNEL_GROUP) ts3lib.requestSetClientChannelGroup(schid, [dcgid] * len(loc_cids), loc_cids, [cldbid] * len(loc_cids)) return for sgid in loc_sgids: ts3lib.requestServerGroupAddClient(schid, sgid, cldbid) ts3lib.requestSetClientChannelGroup( schid, [self.cfg.getint("restrict local", "cgid")] * len(loc_cids), loc_cids, [cldbid] * len(loc_cids)) msg = self.cfg.get("restrict local", "poke") if msg: ts3lib.requestClientPoke(schid, self.last_joined_channel, msg) # ts3lib.requestClientKickFromChannel(schid, clid, msg) def banReason(self): reason = self.cfg.get("ban", "reason") if reason[0].isdigit(): reason = "§" + reason return reason def banUID(self, schid, uid): ts3lib.banadd(schid, "", "", uid, self.cfg.getint("ban", "duration"), self.banReason()) def banIP(self, schid, ip): if not ip: return active = PluginHost.active if "Custom Ban" in active: whitelist = active["Custom Ban"].whitelist if len(whitelist) > 1: if ip in whitelist: ts3lib.printMessageToCurrentTab( "{}: [color=red]Not banning whitelisted IP [b]{}". format(self.name, ip)) return else: ts3lib.printMessageToCurrentTab( "{}: \"Custom Ban\"'s IP Whitelist faulty, please check!". format(self.name)) return ts3lib.banadd(schid, ip, "", "", self.cfg.getint("ban", "duration"), self.banReason()) def onClientMoveEvent(self, schid, clid, oldChannelID, newChannelID, visibility, moveMessage): if schid != ts3lib.getCurrentServerConnectionHandlerID(): return (err, ownID) = ts3lib.getClientID(schid) if clid == ownID: return if oldChannelID == 0: self.last_joined_server = clid (err, ownCID) = ts3lib.getChannelOfClient(schid, ownID) if newChannelID == ownCID: self.last_joined_channel = clid def onServerErrorEvent(self, schid, errorMessage, error, returnCode, extraMessage): if returnCode == self.retcode: return True
class customBan(ts3plugin): path = getScriptPath(__name__) name = "Custom Ban" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 22 requestAutoload = True version = "1.0" author = "Bluscream" description = "Requested by @mrcraigtunstall (217.61.6.128)\nExtended for @SossenSystems (ts3public.de)" offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [(ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CLIENT, 0, "Ban Client", "scripts/%s/ban_client.svg"%__name__)] hotkeys = [] ini = "%s/config.ini"%path dlg = None cfg = ConfigParser() cfg["general"] = { "template": "", "whitelist": "", "ipapi": "True" , "stylesheet": "alternate-background-color: white;background-color: black;"} cfg["last"] = { "ip": "False", "name": "False", "uid": "True", "reason": "", "duration": "0", "expanded": "False", "height": "", "alternate": "False", "ban on doubleclick": "False" } templates = {} whitelist = ["127.0.0.1"] def __init__(self): loadCfg(self.ini, self.cfg) url = self.cfg.get("general", "template") if url: self.nwmc_template = QNetworkAccessManager() self.nwmc_template.connect("finished(QNetworkReply*)", self.loadTemplates) self.nwmc_template.get(QNetworkRequest(QUrl(url))) url = self.cfg.get("general", "whitelist") if url: self.nwmc_whitelist = QNetworkAccessManager() self.nwmc_whitelist.connect("finished(QNetworkReply*)", self.loadWhitelist) self.nwmc_whitelist.get(QNetworkRequest(QUrl(url))) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab("{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded.".format(timestamp(),self.name,self.author)) def stop(self): saveCfg(self.ini, self.cfg) def onMenuItemEvent(self, schid, atype, menuItemID, selectedItemID): if atype != ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CLIENT or menuItemID != 0: return (err, uid) = ts3lib.getClientVariable(schid, selectedItemID, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) if err != ts3defines.ERROR_ok: uid = "" (err, name) = ts3lib.getClientVariable(schid, selectedItemID, ts3defines.ClientProperties.CLIENT_NICKNAME) if err != ts3defines.ERROR_ok: name = "" (err, ip) = ts3lib.getConnectionVariable(schid, selectedItemID, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) self.clid = selectedItemID if err or not ip: ip = "";ts3lib.requestConnectionInfo(schid, selectedItemID); print("requested for", selectedItemID, "on", schid) #TODO: Check if not self.dlg: self.dlg = BanDialog(self, schid, selectedItemID, uid, name, ip) else: self.dlg.setup(self, schid, selectedItemID, uid, name, ip) self.dlg.show() self.dlg.raise_() self.dlg.activateWindow() def onConnectionInfoEvent(self, schid, clid): print(self.name,"> onConnectionInfoEvent", schid, clid) if not hasattr(self, "clid") or clid != self.clid: return (err, ip) = ts3lib.getConnectionVariable(schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if ip and self.dlg: self.dlg.txt_ip.setText(ip) del self.clid def loadTemplates(self, reply): try: data = reply.readAll().data().decode('utf-8') self.templates = loads(data, object_pairs_hook=OrderedDict) if PluginHost.cfg.getboolean("general", "verbose"): print(self.name, "> Downloaded ban templates:", self.templates) except: ts3lib.logMessage(format_exc(), ts3defines.LogLevel.LogLevel_ERROR, "pyTSon", 0) def loadWhitelist(self, reply): try: data = reply.readAll().data().decode('utf-8') self.whitelist = [] for line in data.splitlines(): ip = QHostAddress(line.strip()) if ip.isNull(): print(self.name,">",line,"is not a valid IP! Not adding to whitelist.") else: self.whitelist.append(line.strip()) if PluginHost.cfg.getboolean("general", "verbose"): print(self.name, "> Downloaded ip whitelist:", self.whitelist) except: ts3lib.logMessage(format_exc(), ts3defines.LogLevel.LogLevel_ERROR, "pyTSon", 0)
class YaTQA(ts3plugin): path = getScriptPath(__name__) name = "YaTQA" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 22 requestAutoload = True version = "1.0" author = "Bluscream" description = "Script to utilize YaTQA" offersConfigure = False commandKeyword = "yatqa" infoTitle = None hotkeys = [ # ("yatqa_start", "Start YaTQA"), ("yatqa_connect_current", "Start YaTQA and connect to current server"), ("yatqa_stats_current", "Start YaTQA and check stats"), ("yatqa_blacklist_current", "Start YaTQA and check if current server is blacklisted"), ("yatqa_lookup_dns", "Start YaTQA and lookup (TS)DNS"), ("yatqa_browse_icons", "Start YaTQA and view local icons"), ("yatqa_permission_editor", "Start YaTQA and open permission editor"), ("yatqa_connect_default", "Start YaTQA and connect to default server"), ] menuItems = [ (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 0, "== {0} ==".format(name), ""), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 1, "Start YaTQA", "scripts/%s/yatqa.png"%__name__), (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 2, "Connect to current", "scripts/%s/yatqa.png" % __name__), (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 3, "Statistics", "scripts/%s/stats.png" % __name__), (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 4, "Blacklist", "scripts/%s/blacklist_check.png" % __name__), (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 5, "Lookup (TS)DNS", "scripts/%s/dns.png" % __name__), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 6, "View Icons", "scripts/%s/icons.png"%__name__), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 7, "Permission Editor", "scripts/%s/permission_editor.png"%__name__), # (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 8, "Connect to default", "scripts/%s/default.png"%__name__), (ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL, 10, "== {0} ==".format(name), "") ] yatqa = QProcess() lastpass = {} bin = "C:/Program Files (x86)/YaTQA/yatqa.exe" autoBlackListCheck = False def __init__(self): if isfile(self.bin): self.yatqa = QProcess() self.yatqa.setProgram(self.bin) else: msgBox( "Cannot find YatQA!\nPlease make sure it's installed at\n\n\"{}\"" .format(self.bin)) QDesktopServices.openUrl(QUrl("http://yat.qa/")) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def menuCreated(self): if not self.name in PluginHost.active: return for id in [0, 10]: try: ts3lib.setPluginMenuEnabled(PluginHost.globalMenuID(self, id), False) except: pass def onMenuItemEvent(self, schid, atype, menuItemID, selectedItemID): if atype != ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_GLOBAL: return False keyword = "" if menuItemID == 1: keyword = "yatqa_start" elif menuItemID == 2: keyword = "yatqa_connect_current" elif menuItemID == 3: keyword = "yatqa_stats_current" elif menuItemID == 4: keyword = "yatqa_blacklist_current" elif menuItemID == 5: keyword = "yatqa_lookup_dns" elif menuItemID == 6: keyword = "yatqa_browse_icons" elif menuItemID == 7: keyword = "yatqa_permission_editor" elif menuItemID == 8: keyword = "yatqa_connect_default" else: return self.onHotkeyOrCommandEvent(keyword, schid) def processCommand(self, schid, keyword): return self.onHotkeyOrCommandEvent(keyword, schid) def onHotkeyEvent(self, keyword): return self.onHotkeyOrCommandEvent(keyword) def onHotkeyOrCommandEvent(self, keyword, schid=0): if not schid: schid = ts3lib.getCurrentServerConnectionHandlerID() # (err, status) = ts3lib.getConnectionStatus(schid) # if status != ts3defines.ConnectStatus.STATUS_CONNECTION_ESTABLISHED: return arguments = [] if keyword == "yatqa_start": pass elif keyword == "yatqa_connect_current": (err, ownID) = ts3lib.getClientID(schid) (err, ip) = ts3lib.getConnectionVariable( schid, ownID, ts3defines.ConnectionProperties.CONNECTION_SERVER_IP) (err, port) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerPropertiesRare.VIRTUALSERVER_PORT) title = ("{} > {}".format(self.name, ip)) qport = inputInt(title, "Query Port:", 10011, 1, 65535) name = inputBox(title, "Query Login Name:", "serveradmin") pw = inputBox( title, "Query Login Password:"******"") args = ["-c", ip, qport] if name and pw: args.extend([name, pw, port]) else: args.append(port) self.yatqa.setArguments( args) # IP Query_Port [User Pass] [Voice_Port] elif keyword == "yatqa_stats_current": (err, ownID) = ts3lib.getClientID(schid) (err, ip) = ts3lib.getConnectionVariable( schid, ownID, ts3defines.ConnectionProperties.CONNECTION_SERVER_IP) (err, port) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerPropertiesRare.VIRTUALSERVER_PORT) self.yatqa.setArguments(["-s", ip, port]) # IP elif keyword == "yatqa_blacklist_current": (err, ownID) = ts3lib.getClientID(schid) (err, ip) = ts3lib.getConnectionVariable( schid, ownID, ts3defines.ConnectionProperties.CONNECTION_SERVER_IP) self.yatqa.setArguments(["-b", ip]) # IP elif keyword == "yatqa_lookup_dns": (err, host, port, pw) = ts3lib.getServerConnectInfo(schid) self.yatqa.setArguments(["-d", host]) elif keyword == "yatqa_browse_icons": (err, suid) = ts3lib.getServerVariable( schid, ts3defines.VirtualServerProperties. VIRTUALSERVER_UNIQUE_IDENTIFIER) self.yatqa.setArguments(["-i", suid]) elif keyword == "yatqa_permission_editor": self.yatqa.setArguments(["-p"]) elif keyword == "yatqa_connect_default": self.yatqa.setArguments(["-a"]) else: return False if PluginHost.cfg.getboolean("general", "verbose"): print(self.bin, self.yatqa.arguments()) self.yatqa.start() return True def onClientServerQueryLoginPasswordEvent(self, schid, loginPassword): self.lastpass[schid] = loginPassword ts3lib.printMessage( schid, "Created new query login password: {}".format(loginPassword), ts3defines.PluginMessageTarget.PLUGIN_MESSAGE_TARGET_SERVER) def onConnectStatusChangeEvent(self, schid, newStatus, errorNumber): if not self.autoBlackListCheck: return if newStatus != ts3defines.ConnectStatus.STATUS_CONNECTION_ESTABLISHED: return (err, ownID) = ts3lib.getClientID(schid) (err, ip) = ts3lib.getConnectionVariable( schid, ownID, ts3defines.ConnectionProperties.CONNECTION_SERVER_IP) self.yatqa.setArguments(["-b", ip]) self.yatqa.start()
class customBan(ts3plugin): path = getScriptPath(__name__) name = "Custom Ban" try: apiVersion = pytson.getCurrentApiVersion() except: apiVersion = 22 requestAutoload = False version = "1.0" author = "Bluscream" description = "Requested by @mrcraigtunstall (217.61.6.128)\nExtended for @SossenSystems (ts3public.de)" offersConfigure = False commandKeyword = "" infoTitle = None menuItems = [(ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CLIENT, 0, "Ban Client", "scripts/%s/ban_client.svg" % __name__)] hotkeys = [] ini = "%s/config.ini" % path dlg = None cfg = ConfigParser() cfg["general"] = { "template": "", "whitelist": "", "ipapi": "http://ip-api.com/json/{ip}", "stylesheet": "alternate-background-color: white;background-color: black;" } cfg["last"] = { "ip": "False", "name": "False", "uid": "True", "mytsid": "True", "hwid": "True", "reason": "", "duration": "0", "expanded": "False", "height": "", "alternate": "False", "ban on doubleclick": "False" } templates = {} whitelist = ["127.0.0.1"] waiting_for = (0, 0) mytsids = {} regex_time = re.compile( r'^((?P<years>\d+?)y)?((?P<months>\d+?)M)?((?P<days>\d+?)d)?((?P<hours>\d+?)h)?((?P<minutes>\d+?)m)?((?P<seconds>\d+?)s)?$' ) suffix = "" prefix = "" times = 0 retcodes = [] clid = 0 def __init__(self): loadCfg(self.ini, self.cfg) url = self.cfg.get("general", "template") if url: self.nwmc_template = QNetworkAccessManager() self.nwmc_template.connect("finished(QNetworkReply*)", self.loadTemplates) self.nwmc_template.get(QNetworkRequest(QUrl(url))) url = self.cfg.get("general", "whitelist") if url: self.nwmc_whitelist = QNetworkAccessManager() self.nwmc_whitelist.connect("finished(QNetworkReply*)", self.loadWhitelist) self.nwmc_whitelist.get(QNetworkRequest(QUrl(url))) if PluginHost.cfg.getboolean("general", "verbose"): ts3lib.printMessageToCurrentTab( "{0}[color=orange]{1}[/color] Plugin for pyTSon by [url=https://github.com/{2}]{2}[/url] loaded." .format(timestamp(), self.name, self.author)) def stop(self): saveCfg(self.ini, self.cfg) def onIncomingClientQueryEvent(self, schid, command): cmd = parseCommand(command) if cmd[0] == "notifycliententerview": if not cmd[1]["client_myteamspeak_id"]: return if not schid in self.mytsids: self.mytsids[schid] = {} self.mytsids[schid][cmd[1] ["clid"]] = cmd[1]["client_myteamspeak_id"] elif cmd[0] == "notifyclientleftview": if not schid in self.mytsids: return if not cmd[1]["clid"] in self.mytsids[schid]: return del self.mytsids[schid][cmd[1]["clid"]] def onMenuItemEvent(self, schid, atype, menuItemID, selectedItemID): if atype != ts3defines.PluginMenuType.PLUGIN_MENU_TYPE_CLIENT or menuItemID != 0: return self.waiting_for = (schid, selectedItemID) ts3lib.requestClientVariables(schid, selectedItemID) def checkVars(self, schid, clid): (err, ownID) = ts3lib.getClientID(schid) (err, uid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) if ownID == clid: (err, uid) = ts3lib.getClientSelfVariable( schid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) if err != ts3defines.ERROR_ok or not uid: uid = False (err, mytsid) = ts3lib.getClientVariable(schid, clid, 61) if ownID == clid: (err, mytsid) = ts3lib.getClientSelfVariableAsString(schid, 61) if err != ts3defines.ERROR_ok or not mytsid: mytsid = False (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if err != ts3defines.ERROR_ok or not ip: ip = False return uid, mytsid, ip def onUpdateClientEvent(self, schid, clid, invokerID, invokerName, invokerUID): if schid != self.waiting_for[0]: return if clid != self.waiting_for[1]: return self.waiting_for = (0, 0) (err, uid) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_UNIQUE_IDENTIFIER) if err != ts3defines.ERROR_ok: uid = "" (err, mytsid) = ts3lib.getClientVariable(schid, clid, 61) if err != ts3defines.ERROR_ok or not mytsid: if schid in self.mytsids and clid in self.mytsids[schid]: mytsid = self.mytsids[schid][clid] else: mytsid = "" (err, name) = ts3lib.getClientVariable( schid, clid, ts3defines.ClientProperties.CLIENT_NICKNAME) if err != ts3defines.ERROR_ok: name = "" self.clid = clid type = getServerType(schid) (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if (err != ts3defines.ERROR_ok or not ip) or (ip and ip == "None"): retcode = ts3lib.createReturnCode() self.retcodes.append(retcode) ts3lib.requestConnectionInfo(schid, clid, retcode) (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if not self.dlg: self.dlg = BanDialog(self, schid, clid, uid, name, ip, mytsid, "", type) else: self.dlg.setup(self, schid, clid, uid, name, ip, mytsid, ip, type) self.dlg.show() self.dlg.raise_() self.dlg.activateWindow() def onConnectionInfoEvent(self, schid, clid): if PluginHost.cfg.getboolean("general", "verbose"): print(self.name, "> onConnectionInfoEvent", schid, clid) if not hasattr(self, "clid") or clid != self.clid: return (err, ip) = ts3lib.getConnectionVariable( schid, clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) if ip: (err, ownid) = ts3lib.getClientID(schid) if ip == "None" and clid != ownid: retCode = ts3lib.createReturnCode() self.retcodes.append(retCode) ts3lib.requestConnectionInfo(schid, clid, retCode) return elif self.dlg: self.dlg.txt_ip.setText(ip) del self.clid def onServerErrorEvent(self, schid, errorMessage, error, returnCode, extraMessage): if not returnCode in self.retcodes: return self.retcodes.remove(returnCode) (err, ip) = ts3lib.getConnectionVariable( schid, self.clid, ts3defines.ConnectionProperties.CONNECTION_CLIENT_IP) (err, ownid) = ts3lib.getClientID(schid) if ip and ip != "None" and self.clid != ownid: retCode = ts3lib.createReturnCode() self.retcodes.append(retCode) ts3lib.requestConnectionInfo(schid, self.clid, retCode) def checkIP(self): pass def parse_time(self, time_str): parts = self.regex_time.match(time_str) if not parts: return False parts = parts.groupdict() time_params = {} for (_name, param) in parts.items(): if not param: continue name = _name.lower() param = int(param) if name in ["years", "year", "y"]: name = "days" param = param * 365 elif name in ["months", "month"] or _name == "M": name = "days" param = param * 30.417 time_params[name] = int(param) return timedelta(**time_params) def loadTemplates(self, reply): try: data = reply.readAll().data().decode('utf-8') # if PluginHost.cfg.getboolean("general", "verbose"): json_data = loads(data, object_pairs_hook=OrderedDict) if "prefix" in json_data: self.prefix = json_data["prefix"] if "suffix" in json_data: self.suffix = json_data["suffix"] templates = json_data["templates"] for reason, duration in templates.items(): try: if isinstance(duration, int): continue if duration.isdigit(): templates[reason] = int(duration) elif isinstance(duration, str): if duration.lower() in [ "max", "perm", "permanent", "infinite" ]: templates[reason] = 0 continue delta = self.parse_time(duration) if not delta: print("Can't load", reason, duration) continue templates[reason] = int(delta.total_seconds()) except: ts3lib.logMessage(format_exc(), ts3defines.LogLevel.LogLevel_ERROR, "pyTSon", 0) self.templates = templates if PluginHost.cfg.getboolean("general", "verbose"): print(self.name, "> Downloaded ban templates:", self.templates) except: ts3lib.logMessage(format_exc(), ts3defines.LogLevel.LogLevel_ERROR, "pyTSon", 0) def loadWhitelist(self, reply): try: data = reply.readAll().data().decode('utf-8') self.whitelist = [] for line in data.splitlines(): ip = QHostAddress(line.strip()) if ip.isNull(): print(self.name, ">", line, "is not a valid IP! Not adding to whitelist.") else: self.whitelist.append(line.strip()) if PluginHost.cfg.getboolean("general", "verbose"): print(self.name, "> Downloaded ip whitelist:", self.whitelist) except: ts3lib.logMessage(format_exc(), ts3defines.LogLevel.LogLevel_ERROR, "pyTSon", 0)