// Send your user and nick when you connect function SSIRCTCP::onConnected(%this) { IRCAdmin.NumChannels = 0; IRCAdmin.Object.send("NICK " @ $IRCAdminPrefs::Nick @ "\r\n"); IRCAdmin.Object.send("USER " @ $IRCAdminPrefs::Mask @ " * * :" @ $IRCAdminPrefs::Name @ "\r\n"); if ($IRCAdminPrefs::Password !$= "changeme") IRCAdmin.Msg("NickServ","identify " @ $IRCAdminPrefs::Password); IRCAdmin.Object.send("WHOIS " @ $IRCAdminPrefs::Nick @ "\r\n"); IRCAdmin.Nick = $IRCAdminPrefs::Nick; IRCAdmin.Schedule(10000, NoMOTD); } // Handle error message function SSIRCTCP::onDNSFailed(%this) { error("Couldn't resolve address for IRC server."); } // Handle error message function SSIRCTCP::onConnectFailed(%this) { error("Server for IRC connection not responding."); } // Pass stuff from IRC to IRCAdmin::Process function SSIRCTCP::onLine(%this, %line) { if (isObject(IRCAdmin)) IRCAdmin.Process(%line); } // Create the ScriptObject if (!isObject(IRCAdmin)) { new ScriptObject(IRCAdmin) { class = IRCAdmin; }; IRCAdmin.Object = new TCPObject(SSIRCTCP); } // Parse stuff from IRC function IRCAdmin::Process(%this, %line) { error(%line); %line2 = %line; if (getSubStr(%line,0,1) $= ":") { %line2 = getSubStr(%line2,1,strlen(%line2)-1); %line2 = nextToken(%line2,mask," "); %line2 = nextToken(%line2,command," "); %line2 = nextToken(%line2,to," :"); %data = getSubStr(%line,strStr(%line," :")+2,strLen(%line)); if (strStr(%mask,"!") != -1) { %name = getSubStr(%mask,0,strStr(%mask,"!")); %mask = getSubStr(%mask,strStr(%mask,"!")+1,strLen(%mask)); } } else { %line2 = nextToken(%line2,command," :"); %line2 = nextToken(%line2,data,""); } %this.DoCommand(%line, %mask, %name, %to, %command, %data); } // Handle IRC messages function IRCAdmin::DoCommand(%this, %line, %mask, %name, %to, %command, %data) { switch$(%command) { // Reply to PINGs to let the IRC server know we're still connected case "PING": %this.Ping(%data); // Cancel the reconnect schedule, we're still connected case "PONG": if (isEventPending(%this.Pinger)) { cancel(%this.Pinger); %this.Pinger = %this.schedule(20000, Ping); } case "PRIVMSG": if (getSubStr(%data,0,1) $= "!") %this.Command(%mask,%name,%to,%command,%data); case "JOIN": if (%name $= %this.Nick) { %this.NumChannels++; %last = 0; for (%i = 0; %this.Channels[%i] !$= ""; %i++) %last = %i+1; %this.Channels[%last] = %to; error("[" @ %to @ "] * Now talking in " @ %to); if ($IRCAdminPrefs::Options["echomap"] && $IRCAdminPrefs::Options["echo"]) %this.Msg(%to, %this.Color["red"] @ $Host::GameName @ %this.Color["darkblue"] @ " Map " @ %this.Color["red"] @ $MissionDisplayName @ %this.Color["darkblue"] @ "{" @ $MissionTypeDisplayName @ "}"); } else error("[" @ %to @ "] * " @ %name @ " (" @ %mask @ ")" @ " has joined."); case "PART": if (%name $= %this.Nick) { %number = %this.FindChannel(%to); %this.Channels[%number] = ""; %this.NumChannels--; } else error("[" @ %to @ "] * " @ %name @ " (" @ %mask @ ") " @ "has left."); // Fist line of whois response case "311": if (getWord(%data,0) $= %this.Nick) %this.Mask = getWord(%data,1) @ "@" @ getWord(%data,2); // End of MOTD case "376": if (!%this.Joined) %this.JoinChannels(); } } // Starts joining channels if there is no MOTD - Credit to Ego function IRCAdmin::NoMOTD(%this) { if (!%this.Joined) %this.JoinChannels(); } // Reads our IRCAdminPrefs file, if it doesn't exist create the default prefs // Also load web logging prefs function IRCAdmin::LoadPrefs(%this) { if (!isFile("prefs/IRCAdminPrefs.cs")) { $IRCAdminPrefs::Server = "irc.dynamix.com"; $IRCAdminPrefs::Port = "6667"; $IRCAdminPrefs::Nick = strReplace($Host::GameName," ",""); $IRCAdminPrefs::Password = "changeme"; $IRCAdminPrefs::AdminPassword = "changeme"; $IRCAdminPrefs::SuperAdminPassword = "changeme"; $IRCAdminPrefs::Name = "IRC Admin"; $IRCAdminPrefs::Mask = strReplace($Host::GameName," ",""); $IRCAdminPrefs::QuitMessage = "IRCAdmin for Tribes 2 - By Silverspirit"; $IRCAdminPrefs::Channels[0] = "#T2IRCAdmin"; $IRCAdminPrefs::Options["echo"] = true; $IRCAdminPrefs::Options["echograb"] = true; $IRCAdminPrefs::Options["echojoin"] = true; $IRCAdminPrefs::Options["echoleave"] = true; $IRCAdminPrefs::Options["echodrop"] = true; $IRCAdminPrefs::Options["echoreturn"] = true; $IRCAdminPrefs::Options["echocap"] = true; $IRCAdminPrefs::Options["echomap"] = true; $IRCAdminPrefs::Options["echokill"] = true; $IRCAdminPrefs::Options["allowscores"] = true; $IRCAdminPrefs::Options["locallog"] = true; $IRCAdminPrefs::Options["weblog"] = true; $IRCAdminPrefs::Options["scoresdelay"] = 3; %this.SavePrefs(); } else exec("prefs/IRCAdminPrefs.cs"); %file = new FileObject(); %file.openForRead("prefs/IRCAdminWebPrefs.cs"); for (%i = 0; !%file.isEOF(); %i++) { %this.WebServers[%i] = trim(%file.readLine()); %this.WebUrls[%i] = trim(%file.readLine()); } %file.close(); %file.delete(); } // Save prefs function IRCAdmin::SavePrefs(%this) { export("$IRCAdminPrefs::*","prefs/IRCAdminPrefs.cs"); } // Connects to an IRC server function IRCAdmin::Start(%this) { if (isEventPending(%this.Pinger)) cancel(%this.Pinger); %this.Joined = false; %this.Null = "\x02\x02"; %this.Bold = "\x02"; %this.Invert = "\x16"; %this.Underline = "\x1f"; %this.Color["white"] = "\x030" @ %this.Null; %this.Color["black"] = "\x031" @ %this.Null; %this.Color["darkblue"] = "\x032" @ %this.Null; %this.Color["darkgreen"] = "\x033" @ %this.Null; %this.Color["red"] = "\x034" @ %this.Null; %this.Color["brown"] = "\x035" @ %this.Null; %this.Color["purple"] = "\x036" @ %this.Null; %this.Color["orange"] = "\x037" @ %this.Null; %this.Color["yellow"] = "\x038" @ %this.Null; %this.Color["green"] = "\x039" @ %this.Null; %this.Color["aqua"] = "\x0310" @ %this.Null; %this.Color["lightblue"] = "\x0311" @ %this.Null; %this.Color["blue"] = "\x0312" @ %this.Null; %this.Color["pink"] = "\x0313" @ %this.Null; %this.Color["gray"] = "\x0314" @ %this.Null; %this.Color["silver"] = "\x0315" @ %this.Null; %this.Colors[0] = "255 255 255"; %this.Colors[1] = "0 0 0"; %this.Colors[2] = "0 0 143"; %this.Colors[3] = "0 148 0"; %this.Colors[4] = "255 0 0"; %this.Colors[5] = "123 0 0"; %this.Colors[6] = "168 0 185"; %this.Colors[7] = "255 123 0"; %this.Colors[8] = "255 255 0"; %this.Colors[9] = "0 255 0"; %this.LoadPrefs(); %this.Object.Connect("IP:" @ $IRCAdminPrefs::Server @ ":" @ $IRCAdminPrefs::Port); } // Join channels and start the endless PING function IRCAdmin::JoinChannels(%this) { for (%i = 0; $IRCAdminPrefs::Channels[%i] !$= ""; %i++) %this.Join($IRCAdminPrefs::Channels[%i]); %this.Joined = true; %this.Pinger = %this.schedule(20000, Ping); } // See if we're in a channel and return it's ID if we are function IRCAdmin::FindChannel(%this, %channel) { for (%i = 0; %i < %this.NumChannels; %i++) if (%this.Channels[%i] $= %channel) return %i; return -1; } // Send a PING function IRCAdmin::Ping(%this, %data) { if (%data $= "") %data = $IRCAdminPrefs::Server; %this.Object.Send("PING " @ %data @ "\r\n"); %this.Pinger = %this.schedule(10000, Start); } // Send a PONG function IRCAdmin::Pong(%this, %data) { if (%data $= "") %data = $IRCAdminPrefs::Server; %this.Object.Send("PING " @ %data @ "\r\n"); } // Send a PRIVMSG function IRCAdmin::Msg(%this, %name, %message) { if (%message !$= "") { %this.Object.Send("PRIVMSG " @ %name @ " :" @ %message @ "\r\n"); %this.DoCommand(%this.Mask, %this.Nick @ "~" @ %name, "PRIVMSG", %message); } } // Send a NOTICE function IRCAdmin::Notice(%this, %name, %message) { %this.Object.Send("NOTICE " @ %name @ " :" @ %message @ "\r\n"); } // Send a MODE function IRCAdmin::Mode(%this, %name, %mode) { %this.Object.Send("MODE " @ %name SPC %mode @ "\r\n"); } // Send a JOIN function IRCAdmin::Join(%this, %channel) { %this.Object.Send("JOIN " @ %channel @ "\r\n"); } // Send a PART function IRCAdmin::Part(%this, %channel) { %this.Object.Send("PART " @ %channel @ "\r\n"); } // Send a WHOIS function IRCAdmin::Whois(%this, %nick) { %this.Object.Send("WHOIS " @ %nick @ "\r\n"); } // Send a QUIT function IRCAdmin::Quit(%this, %message) { %this.SavePrefs(); if (isEventPending(%this.Pinger)) cancel(%this.Pinger); if (%message $= "") %message = $IRCAdminPrefs::QuitMessage; %this.Object.Send("QUIT :" @ %message @ "\r\n"); %this.Joined = false; } // Get the command and parameters, and pass them where they should go function IRCAdmin::Command(%this, %mask, %name, %to, %command, %data) { %data = nextToken(%data,command," "); %data = nextToken(%data,param1," "); %data = nextToken(%data,param2,""); switch$(%command) { case "!identify": IRCAdmin.CheckIdentify(%name,%param1); case "!kick": IRCAdmin.Kick(%name,%param1,%param2, true); case "!ban": IRCAdmin.Ban(%name,%param1,%param2, true); case "!kickpassive": IRCAdmin.Kick(%name,%param1,%param2, false); case "!banpassive": IRCAdmin.Ban(%name,%param1,%param2, false); case "!stat": IRCAdmin.Stat(%name); case "!find": IRCAdmin.Find(%name,%param1); case "!trackname": IRCAdmin.TrackName(%name,%param1); case "!trackip": IRCAdmin.TrackIP(%name,%param1); case "!trackguid": IRCAdmin.TrackGUID(%name,%param1); case "!scores": IRCAdmin.Scores(%name, %to); case "!set": IRCAdmin.Set(%name,%param1,%param2); case "!view": IRCAdmin.View(%name,%param1); case "!msg": IRCAdmin.SendMsg(%name,"",%param1 SPC %param2,"all",true); case "!msgteam": IRCAdmin.SendMsg(%name,%param1,%param2,"team",true); case "!msgto": IRCAdmin.SendMsg(%name,%param1,%param2,"private",true); case "!msgexcept": IRCAdmin.SendMsg(%name,%param1,%param2,"except",true); case "!msgpassive": IRCAdmin.SendMsg(%name,"",%param1 SPC %param2,"all",false); case "!msgteampassive": IRCAdmin.SendMsg(%name,%param1,%param2,"team",false); case "!msgtopassive": IRCAdmin.SendMsg(%name,%param1,%param2,"private",false); case "!msgexceptpassive": IRCAdmin.SendMsg(%name,%param1,%param2,"except",false); case "!kill": IRCAdmin.Kill(%name,%param1,true); case "!killpassive": IRCAdmin.Kill(%name,%param1,false); case "!commands": IRCAdmin.Commands(%name); case "!help": IRCAdmin.Help(%name,%param1,%param2); case "!strike": IRCAdmin.Strike(%name,%param1,true); case "!strikepassive": IRCAdmin.Strike(%name,%param1,false); case "!admin": IRCAdmin.Admin(%name,%param1,true,false); case "!superadmin": IRCAdmin.Admin(%name,%param1,true,true); case "!meteor": IRCAdmin.Meteor(%name,%param1,true); case "!cp": IRCAdmin.Print(%name,"",%param1 SPC %param2,'CenterPrint',"all",true); case "!cpto": IRCAdmin.Print(%name,%param1,%param2,'CenterPrint',"private",true); case "!cpteam": IRCAdmin.Print(%name,%param1,%param2,'CenterPrint',"team",true); case "!cpexcept": IRCAdmin.Print(%name,%param1,%param2,'CenterPrint',"except",true); case "!cppassive": IRCAdmin.Print(%name,"",%param1 SPC %param2,'CenterPrint',"all",false); case "!cptopassive": IRCAdmin.Print(%name,%param1,%param2,'CenterPrint',"private",false); case "!cpteampassive": IRCAdmin.Print(%name,%param1,%param2,'CenterPrint',"team",false); case "!cpexceptpassive": IRCAdmin.Print(%name,%param1,%param2,'CenterPrint',"except",false); case "!bp": IRCAdmin.Print(%name,"",%param1 SPC %param2,'BottomPrint',"all",true); case "!bpto": IRCAdmin.Print(%name,%param1,%param2,'BottomPrint',"private",true); case "!bpteam": IRCAdmin.Print(%name,%param1,%param2,'BottomPrint',"team",true); case "!bpexcept": IRCAdmin.Print(%name,%param1,%param2,'BottomPrint',"except",true); case "!bppassive": IRCAdmin.Print(%name,"",%param1 SPC %param2,'BottomPrint',"all",false); case "!bptopassive": IRCAdmin.Print(%name,%param1,%param2,'BottomPrint',"private",false); case "!bpteampassive": IRCAdmin.Print(%name,%param1,%param2,'BottomPrint',"team",false); case "!bpexceptpassive": IRCAdmin.Print(%name,%param1,%param2,'BottomPrint',"except",false); case "!listmaps": IRCAdmin.ListMaps(%name,%param1); case "!listtypes": IRCAdmin.ListTypes(%name,%param1); case "!mapffa": IRCAdmin.Map(%name,%param1,%param2,false); case "!maptourney": IRCAdmin.Map(%name,%param1,%param2,true); case "!eval": IRCAdmin.Eval(%name,%param1 SPC %param2); case "!changeteam": IRCAdmin.ChangeTeam(%name,%param1,%param2); case "!maxplayers": IRCAdmin.MaxPlayers(%name,%param1); case "!joinpass": IRCAdmin.JoinPass(%name,%param1); case "!adminpass": IRCAdmin.AdminPass(%name,%param1); case "!superadminpass": IRCAdmin.SuperAdminPass(%name,%param1); } } // Clients identify themselves as admins function IRCAdmin::CheckIdentify(%this, %name, %password) { if (%this.CheckSuperAdmin(%name,1)) { // Remove a client from the super admin list if (%password $= "deadmin") { if (strStr($IRCSuperAdmins,%name) + strLen(%name) == strLen($IRCSuperAdmins)) $IRCSuperAdmins = strReplace($IRCSuperAdmins,%name,""); else $IRCSuperAdmins = strReplace($IRCSuperAdmins,%name @ "\t",""); %this.Msg(%name, %this.Color["darkblue"] @ "You have been removed from the super admin list."); } else // They are already an super admin %this.Msg(%name, %this.Color["darkblue"] @ "You are already identified as a super admin. Use !identify deadmin to de-admin yourself."); } else if (%this.CheckAdmin(%name,1)) { // Remove a client from the admin list if (%password $= "deadmin") { if (strStr($IRCAdmins,%name) + strLen(%name) == strLen($IRCAdmins)) $IRCAdmins = strReplace($IRCAdmins,%name,""); else $IRCAdmins = strReplace($IRCAdmins,%name @ "\t",""); %this.Msg(%name, %this.Color["darkblue"] @ "You have been removed from the admin list."); } else // They are already an admin %this.Msg(%name, %this.Color["darkblue"] @ "You are already identified as an admin. Use !identify deadmin to de-admin yourself."); } else { // Password matches if (%password $= $IRCAdminPrefs::AdminPassword) { // Password is at default, deny if (%password $= "changeme") { %this.Msg(%name, %this.Color["darkblue"] @ "Admin access denied until password is changed from default."); return; } // Password not set to default, grant admin %this.Msg(%name, %this.Color["darkblue"] @ "You are now identified as an admin."); if ($IRCAdmins $= "") $IRCAdmins = %name; else $IRCAdmins = $IRCAdmins TAB %name; } else if (%password $= $IRCAdminPrefs::SuperAdminPassword) { // Password is at default, deny if (%password $= "changeme") { %this.Msg(%name, %this.Color["darkblue"] @ "Super Admin access denied until password is changed from default."); return; } // Password not set to default, grant super admin %this.Msg(%name, %this.Color["darkblue"] @ "You are now identified as a super admin."); if ($IRCSuperAdmins $= "") $IRCSuperAdmins = %name; else $IRCSuperAdmins = $IRCSuperAdmins TAB %name; } else %this.Msg(%name, %this.Color["darkblue"] @ "Invalid password."); } } // See if a certain client is an admin function IRCAdmin::CheckAdmin(%this, %name, %noEcho) { if (%this.CheckSuperAdmin(%name, 1)) return true; for (%i = 0; getField($IRCAdmins,%i) !$= ""; %i++) { if (getField($IRCAdmins,%i) $= %name) return true; } if (!%noEcho) %this.Msg(%name, %this.Color["darkblue"] @ "Admin level required."); return false; } // See if a certain client is a super admin function IRCAdmin::CheckSuperAdmin(%this, %name, %noEcho) { for (%i = 0; getField($IRCSuperAdmins,%i) !$= ""; %i++) { if (getField($IRCSuperAdmins,%i) $= %name) return true; } if (!%noEcho) %this.Msg(%name, %this.Color["darkblue"] @ "Super Admin level required."); return false; } // Kick a player function IRCAdmin::Kick(%this, %admin, %name, %reason, %tell) { if (%this.CheckAdmin(%admin)) { %client = %this.FindSimilarClient(%name); if (!%client) %this.Msg(%admin, %this.Color["darkblue"] @ "No player found."); else { %name = %this.GetFullName(%client); %this.KickClient(%client, %client.guid, %admin, %reason, %tell); %this.Msg(%admin, %this.Color["darkblue"] @ "Kicked " @ %this.Color["red"] @ %name @ %this.Color["darkblue"] @ "."); } } } // Ban a player function IRCAdmin::Ban(%this, %admin, %name, %reason, %tell) { if (%this.CheckSuperAdmin(%admin)) { %client = %this.FindSimilarClient(%name); if (!%client) %this.Msg(%admin, %this.Color["darkblue"] @ "No player found."); else { %name = %this.GetFullName(%client); %this.BanClient(%client, %admin, %reason, %tell); %this.Msg(%admin, %this.Color["darkblue"] @ "Banned " @ %this.Color["red"] @ %name @ %this.Color["darkblue"] @ "."); } } } // Get the current map, gametpe, and all players on each team function IRCAdmin::Stat(%this, %admin) { if (%this.CheckAdmin(%admin)) { if ($CurrentMission $= "") %message = %this.Color["darkblue"] @ "No game running."; else { %message = %this.Color["darkblue"] @ "Map{" @ %this.Color["red"] @ $MissionDisplayName @ %this.Color["darkblue"] @ "} Type{" @ %this.Color["red"] @ $MissionTypeDisplayName @ %this.Color["darkblue"] @ "} Max Players{" @ %this.Color["red"] @ $Host::MaxPlayers @ %this.Color["darkblue"] @ "} Join PW{" @ %this.Color["red"] @ $Host::Password @ %this.Color["darkblue"] @ "} Admin PW{" @ %this.Color["red"] @ $Host::AdminPassword @ %this.Color["darkblue"] @ "} Super Admin PW{" @ %this.Color["red"] @ $Host::SuperAdminPassword @ %this.Color["darkblue"] @ "}"; for (%i = 0; %i < ClientGroup.getCount(); %i++) { if (%team[ClientGroup.getObject(%i).team] $= "") %team[ClientGroup.getObject(%i).team] = %this.GetFullName(ClientGroup.getObject(%i)); else %team[ClientGroup.getObject(%i).team] = %team[ClientGroup.getObject(%i).team] @ ", " @ %this.GetFullName(ClientGroup.getObject(%i)); } for (%i = 0; isObject("Team" @ %i); %i++) { %message = %message SPC getTaggedString(Game.getTeamName(%i)) @ ":" @ %this.Color["red"] @ %this.GetTeamSize(%i) @ %this.Color["darkblue"] @ "{" @ %this.Color["red"] @ %team[%i] @ %this.Color["darkblue"] @ "}"; } } %this.Msg(%admin,%message); } } // Search for a player and give their name, ip, guid, score, ping, team, and teamname function IRCAdmin::Find(%this, %admin, %name) { if (%this.CheckAdmin(%admin)) { if ($CurrentMission $= "") %this.Msg(%admin, %this.Color["darkblue"] @ "No game running."); else { %client = %this.FindSimilarClient(%name); if (!%client) %this.Msg(%admin, %this.Color["darkblue"] @ "No player found."); else { %name = %this.GetFullName(%client); %this.Msg(%admin, %this.Color["darkblue"] @ %name @ " IP{" @ %this.Color["red"] @ %client.getAddress() @ %this.Color["darkblue"] @ "} GUID{" @ %this.Color["red"] @ %client.guid @ %this.Color["darkblue"] @ "} Score{" @ %this.Color["red"] @ %client.score @ %this.Color["darkblue"] @ "} Ping{" @ %this.Color["red"] @ %client.getPing() @ %this.Color["darkblue"] @ "} Team{" @ %this.Color["red"] @ %client.team @ %this.Color["darkblue"] @ "} TeamName{" @ %this.Color["red"] @ getTaggedString(Game.getTeamName(%client.team)) @ %this.Color["darkblue"] @ "}"); } } } } // Search for a player in the logfile and reply with the ips and guids of each occurance function IRCAdmin::TrackName(%this, %admin, %name) { if (%this.CheckAdmin(%admin)) { if (isFile("connections.txt")) { %file = new FileObject(); %file.openForRead("connections.txt"); while (!%file.isEOF()) { %line = %file.readLine(); if (strStr(strLwr(getField(%line,0)),strLwr(%name)) != -1) { %name = getField(%line,0); %foundname = getField(%line,0); if (strStr(%IPs,getField(%line,1)) == -1) if (%IPs $= "") %IPs = getField(%line,1); else %IPs = %IPs @ ", " @ getField(%line,1); if (strStr(%GUIDs,getField(%line,2)) == -1) if (%GUIDs $= "") %GUIDs = getField(%line,2); else %GUIDs = %GUIDs @ ", " @ getField(%line,2); } } if (%foundname $= "") %this.Msg(%admin, %this.Color["darkblue"] @ "Name not found: " @ %this.Color["red"] @ %name @ %this.Color["darkblue"] @ "."); else %this.Msg(%admin, %this.Color["darkblue"] @ "Name found: " @ %this.Color["red"] @ %foundname @ %this.Color["darkblue"] @ " IPs{" @ %this.Color["red"] @ %IPs @ %this.Color["darkblue"] @ "} GUIDs{" @ %this.Color["red"] @ %GUIDs @ %this.Color["darkblue"] @ "}"); %file.close(); %file.delete(); } else %this.Msg(%admin, %this.Color["darkblue"] @ "No log file."); } } // Search for an ip in the logfile and reply with the names and guids of each occurance function IRCAdmin::TrackIP(%this, %admin, %ip) { if (%this.CheckAdmin(%admin)) { if (isFile("connections.txt")) { %file = new FileObject(); %file.openForRead("connections.txt"); while (!%file.isEOF()) { %line = %file.readLine(); if (getField(%line,1) $= %ip) { %foundip = getField(%line,1); if (strStr(%names,getField(%line,0)) == -1) if (%names $= "") %names = getField(%line,0); else %names = %names @ ", " @ getField(%line,0); if (strStr(%GUIDs,getField(%line,2)) == -1) if (%GUIDs $= "") %GUIDs = getField(%line,2); else %GUIDs = %GUIDs @ ", " @ getField(%line,2); } } if (%foundip $= "") %this.Msg(%admin, %this.Color["darkblue"] @ "IP not found: " @ %this.Color["red"] @ %ip @ %this.Color["darkblue"] @ "."); else %this.Msg(%admin, %this.Color["darkblue"] @ "IP found: " @ %this.Color["red"] @ %foundip @ %this.Color["darkblue"] @ " Names{" @ %this.Color["red"] @ %names @ %this.Color["darkblue"] @ "} GUIDs{" @ %this.Color["red"] @ %GUIDs @ %this.Color["darkblue"] @ "}"); %file.close(); %file.delete(); } else %this.Msg(%admin, %this.Color["darkblue"] @ "No log file."); } } // Search for a guid in the logfile and reply with the ips and names of each occurance function IRCAdmin::TrackGUID(%this, %admin, %guid) { if (%this.CheckAdmin(%admin)) { if (isFile("connections.txt")) { %file = new FileObject(); %file.openForRead("connections.txt"); while (!%file.isEOF()) { %line = %file.readLine(); if (getField(%line,2) $= %guid) { %foundguid = getField(%line,2); if (strStr(%names,getField(%line,0)) == -1) if (%names $= "") %names = getField(%line,0); else %names = %names @ ", " @ getField(%line,0); if (strStr(%IPs,getField(%line,1)) == -1) if (%IPs $= "") %IPs = getField(%line,1); else %IPs = %IPS @ ", " @ getField(%line,1); } } if (%foundguid $= "") %this.Msg(%admin, %this.Color["darkblue"] @ "GUID not found: " @ %this.Color["red"] @ %guid @ %this.Color["darkblue"] @ "."); else %this.Msg(%admin, %this.Color["darkblue"] @ "GUID found: " @ %this.Color["red"] @ %foundguid @ %this.Color["darkblue"] @ " Names{" @ %this.Color["red"] @ %names @ %this.Color["darkblue"] @ "} IPs{" @ %this.Color["red"] @ %IPs @ %this.Color["darkblue"] @ "}"); %file.close(); %file.delete(); } else %this.Msg(%admin, %this.Color["darkblue"] @ "No log file."); } } // This command can be used by ANYONE, but is regulated on how often it can be used // If at least half a team is a member of the same tribe, the name is replaces with that tribe name function IRCAdmin::Scores(%this, %name, %to) { // Don't do anything unless we're allowed to if ($IRCAdminPrefs::Options["allowscores"]) { if (%to $= IRCAdmin.Nick) %to = %name; if ($CurrentMission $= "") %message = %this.Color["darkblue"] @ "No game running."; else { %message = %this.Color["darkblue"] @ "Map{" @ %this.Color["red"] @ $CurrentMission @ %this.Color["darkblue"] @ "}"; // Go through every player, and add them to their teams lists if they are on tribes for (%i = 0; %i < ClientGroup.getCount(); %i++) { %tribe = %this.GetTribe(ClientGroup.getObject(%i)); if (%tribe !$= "0") { if (%tribes[ClientGroup.getObject(%i).team] $= "") %tribes[ClientGroup.getObject(%i).team] = %tribe; else %tribes[ClientGroup.getObject(%i).team] = %tribes[ClientGroup.getObject(%i).team] TAB %tribe; if (%tribelist[ClientGroup.getObject(%i).team] $= "") %tribelist[ClientGroup.getObject(%i).team] = %tribe; else if (strStr(%tribelist[ClientGroup.getObject(%i).team],%tribe) == -1) %tribelist[ClientGroup.getObject(%i).team] = %tribelist[ClientGroup.getObject(%i).team] TAB %tribe; } } // Wow complicated =\ Count the members of each tribe on each team (skip observers) // and set that tribe as the teamname if that tribe occupies 50% of the team for (%i = 1; isObject("Team" @ %i); %i++) { %teamName[%i] = getTaggedString(Game.getTeamName(%i)); for (%ii = 0; %ii < getFieldCount(%tribelist[%i]); %ii++) { for (%iii = %start = 0; strPos(%tribes[%i],getField(%tribelist[%i],%ii),%start) != -1; %iii++) { if (%iii+1 >= mCeil(%this.GetTeamSize(%i)/2)) %teamName[%i] = getField(%tribelist[%i],%ii); %start += strLen(getField(%tribelist[%i],%ii)); } } %message = %message SPC %teamName[%i] @ "{" @ %this.Color["red"] @ mFloor($teamScore[%i]/100) @ %this.Color["darkblue"] @ "}"; } } %this.Msg(%to, %message); $IRCAdminPrefs::Options["allowscores"] = false; // Set the delay to allow the scores command again %this.ScoreSchedule = %this.schedule($IRCAdminPrefs::Options["scoresdelay"] * 1000, AllowScoresCommand); } } // Allow or disallow the scores command function IRCAdmin::AllowScoresCommand(%this) { $IRCAdminPrefs::Options["allowscores"] = true; } // Change an option function IRCAdmin::Set(%this, %admin, %option, %setting) { if (%this.CheckAdmin(%admin)) { if (%setting $= "on") %setting = true; if (%setting $= "off") %setting = false; $IRCAdminPrefs::Options[strLwr(%option)] = %setting; // If we're turning off the scores command, make sure we delete the schedule to turn it back on switch$(strLwr(%option)) { case "allowscores": if(isEventPending(%this.ScoreSchedule)) cancel(%this.ScoreSchedule); } %this.Msg(%admin, %this.Color["darkblue"] @ "Option set."); %this.SavePrefs(); } } function IRCAdmin::View(%this, %admin, %option) { if (%this.CheckAdmin(%admin)) { %setting = $IRCAdminPrefs::Options[%option]; if (%setting) %setting = "on"; else if (!%setting) if (%setting $= "") { %this.Msg(%admin, %this.Color["red"] @ %option @ %this.Color["darkblue"] @ " is not an option."); return; } else %setting = "off"; %this.Msg(%admin, %this.Color["darkblue"] @ "Option " @ %this.Color["red"] @ %option @ %this.Color["darkblue"] @ " is " @ %this.Color["red"] @ %setting @ %this.Color["darkblue"] @ "."); } } // Send a message to certain players chathuds function IRCAdmin::SendMsg(%this, %admin, %name, %message, %type, %tell) { if (%this.CheckAdmin(%admin)) { %message = trim(%message); if (%tell) %header = %admin @ " from IRC: "; else %header = "Message from IRC: "; switch$(%type) { case "all": serverPlay2D(StationAccessDeniedSound); messageAll('msgClient', "\c4" @ %header @ %message); case "team": for (%i = 0; %i < ClientGroup.getCount(); %i++) if (ClientGroup.getObject(%i).team == %name) ClientGroup.getObject(%i).play2D(StationAccessDeniedSound); messageTeam(%name, 'msgClient', "\c3" @ %header @ %message); case "private": if (%this.FindSimilarClient(%name)) { %this.FindSimilarClient(%name).play2D(StationAccessDeniedSound); messageClient(%this.FindSimilarClient(%name), 'msgClient', "\c5" @ %header @ %message); } else { %this.Msg(%admin, %this.Color["darkblue"] @ "Player not found."); return; } case "except": %client = %this.FindSimilarClient(%name); for (%i = 0; %i < ClientGroup.getCount(); %i++) if (ClientGroup.getObject(%i) != %client) ClientGroup.getObject(%i).play2D(StationAccessDeniedSound); messageAllExcept(%client, -1, 'msgClient', "\c4" @ %header @ "(not sent to " @ %this.GetFullName(%this.FindSimilarClient(%name)) @ ") " @ %message); } %this.Msg(%admin, %this.Color["darkblue"] @ "Message sent."); } } // Kill a player function IRCAdmin::Kill(%this, %admin, %name, %tell) { if (%this.CheckAdmin(%admin)) { %client = %this.FindSimilarClient(%name); if (%client) { if (%client.player) { %client.player.scriptKill(); if (%tell) { messageAllExcept(%client, -1, 'msgClient', "\c5" @ %this.GetFullName(%client) @ " was killed by " @ %admin @ "."); messageClient(%client, 'msgClient', "\c5You have been killed by " @ %admin @ "."); } %this.Msg(%admin, %this.Color["darkblue"] @ "Killed " @ %this.Color["red"] @ %this.GetFullName(%client) @ %this.Color["darkblue"] @ "."); } else %this.Msg(%admin, %this.Color["darkblue"] @ "Player isn't spawned."); } else %this.Msg(%admin, %this.Color["darkblue"] @ "No player found."); } } // Yay! Lighting! Zap a player with a pretty bolt function IRCAdmin::Strike(%this, %admin, %name, %tell) { if (%this.CheckAdmin(%admin)) { %client = %this.FindSimilarClient(%name); if (%client) { if (%client.player) { // Create the lightning area new Lightning(AdminLightning) { position = %client.player.getPosition(); rotation = "1 0 0 0"; scale = "1 1 300"; dataBlock = "DefaultStorm"; strikesPerMinute = "5000"; strikeWidth = "2.5"; chanceToHitTarget = "1"; strikeRadius = "5"; boltStartRadius = "20"; color = "1.000000 1.000000 1.000000 1.000000"; fadeColor = "0.100000 0.100000 1.000000 1.000000"; useFog = "1"; locked = "true"; }; // Delete the lightning area in 3 seconds AdminLightning.schedule(1000, delete); // Check and see if the player died %this.schedule(1000, CheckStrike, %admin, %name, %tell); } else %this.Msg(%admin, %this.Color["darkblue"] @ "Player isn't spawned."); } else %this.Msg(%admin, %this.Color["darkblue"] @ "No player found."); } } // See if the lightning strike killed the player function IRCAdmin::CheckStrike(%this, %admin, %name, %tell) { %client = %this.FindSimilarClient(%name); if (!%client.player) { if (%tell) { messageAllExcept(%client, -1, 'msgClient', "\c5" @ %this.GetFullName(%client) @ " was struck by " @ %admin @ "'s lightning bolt."); messageClient(%client, 'msgClient', "\c5You have been struck by " @ %admin @ "'s lighting bolt."); } %this.Msg(%admin, %this.Color["darkblue"] @ "Struck " @ %this.Color["red"] @ %this.GetFullName(%client) @ %this.Color["darkblue"] @ "."); } } // Create meteors that don't do anything besides look cool and shake your screen a lot if they hit you // However it doesn't work, when I hosted the meteors always went for me regardless of who I told them to hit function IRCAdmin::Meteor(%this, %admin, %name, %tell) { if (%this.CheckAdmin(%admin)) { %client = %this.FindSimilarClient(%name); if (%client) { if (%client.player) { // Create the "FireballAtmosphere" aka meteors new FireballAtmosphere(AdminMeteor) { position = %client.player.getPosition(); rotation = "1 0 0 0"; scale = "1 1 5000"; dataBlock = "fireball"; dropRadius = "0"; dropsPerMinute = "240"; minDropAngle = "0"; maxDropAngle = "0"; startVelocity = "-300"; dropHeight = "1000"; dropDir = "0 0 1"; locked = "true"; }; // Delete the FireballAtmosphere in 1 second AdminMeteor.schedule(1000, delete); } else %this.Msg(%admin, %this.Color["darkblue"] @ "Player isn't spawned."); } else %this.Msg(%admin, %this.Color["darkblue"] @ "No player found."); } } // Give a player in the game admin, or remove their admin function IRCAdmin::Admin(%this, %admin, %name, %normal, %super) { if (%this.CheckAdmin(%admin)) { %client = %this.FindSimilarClient(%name); %name = %this.GetFullName(%client); if (%client) { %client.isAdmin = %normal; %client.isSuperAdmin = %super; if (%normal && %super) { MessageAll('MsgSuperAdminPlayer', '\c2%2.', %client, %this.GetFullName(%client) @ " has been made a Super Admin by " @ %admin); %message = "Gave " @ %this.Color["red"] @ %name @ %this.Color["darkblue"] @ " SuperAdmin."; } else if (%normal && !%super) { MessageAll('MsgAdminPlayer', '\c2%2.', %client, %this.GetFullName(%client) @ " has been made an Admin by " @ %admin); %message = "Gave " @ %this.Color["red"] @ %name @ %this.Color["darkblue"] @ " Admin."; } } else %message = "No player found."; %this.Msg(%admin,%this.Color["darkblue"] @ %message); } } // BottomPrint or CenterPrint messages to clients function IRCAdmin::Print(%this, %admin, %name, %message, %printtype, %type, %tell) { if (%this.CheckAdmin(%admin)) { error(%printtype); %message = trim(%message); if (%tell) %header = " from " @ %admin @ ": "; else %header = " from IRC: "; switch$(%type) { case "all": serverPlay2D(StationAccessDeniedSound); for (%i = 0; %i < ClientGroup.getCount(); %i++) commandToClient(ClientGroup.getObject(%i),%printtype,"Global message" @ %header @ %message,5,1); case "team": for (%i = 0; %i < ClientGroup.getCount(); %i++) if (ClientGroup.getObject(%i).team == %name) { ClientGroup.getObject(%i).play2D(StationAccessDeniedSound); commandToClient(ClientGroup.getObject(%i),%printtype,"Team message" @ %header @ %message,5,1); } case "private": if (%this.FindSimilarClient(%name)) { %this.FindSimilarClient(%name).play2D(StationAccessDeniedSound); commandToClient(%this.FindSimilarClient(%name),%printtype,"Private message" @ %header @ %message,5,1); } else { %this.Msg(%admin, %this.Color["darkblue"] @ "Player not found."); return; } case "except": %client = %this.FindSimilarClient(%name); for (%i = 0; %i < ClientGroup.getCount(); %i++) if (ClientGroup.getObject(%i) != %client) { ClientGroup.getObject(%i).play2D(StationAccessDeniedSound); commandToClient(ClientGroup.getObject(%i),%printtype,"Global message except " @ %this.GetFullName(%client) @ %header @ %message,5,1); } } %this.Msg(%admin, %this.Color["darkblue"] @ "Message sent."); } } // List all gametypes function IRCAdmin::ListTypes(%this, %admin) { if (%this.CheckAdmin(%admin)) { for (%i = 0; %i < $HostTypeCount; %i++) { if (%i == 0) %message = %this.Color["darkblue"] @ "Types{" @ %this.Color["red"] @ $HostTypeName[%i]; else %message = %message @ ", " @ $HostTypeName[%i]; } %this.Msg(%admin, %message @ %this.Color["darkblue"] @ "}"); } } // List all maps that are members of a certain gametype function IRCAdmin::ListMaps(%this, %admin, %type) { if (%this.CheckAdmin(%admin)) { for (%i = 0; %i < $HostTypeCount; %i++) { if ($HostTypeName[%i] $= %type) { %found = true; %name = $HostTypeName[%i]; %type = %i; } } if (%found) { %msg = 0; for (%i = 0; %i < $HostMissionCount[%type]; %i++) { %idx = $HostMission[%type, %i]; if (%i == 0) %message[%msg] = %this.Color["darkblue"] @ %name @ "{" @ %this.Color["red"] @ $HostMissionFile[%idx]; else { if (strLen(%message[%msg]) > 420) { %message[%msg] = %message[%msg] @ "..."; %msg++; %message[%msg] = %this.Color["red"] @ "..." @ $HostMissionFile[%idx]; } else %message[%msg] = %message[%msg] @ ", " @ $HostMissionFile[%idx]; } } %message[%msg] = %message[%msg] @ %this.Color["darkblue"] @ "}"; } else %message[0] = %this.Color["darkblue"] @ "Invalid type. Use" @ %this.Color["red"] @ " !listtypes " @ %this.Color["darkblue"] @ "to see a list of types."; for (%i = 0; %message[%i] !$= ""; %i++) if (%i == 0) %this.Msg(%admin, %message[%i]); else %this.schedule(%i * 2000, Msg, %admin, %message[%i]); } } // Change the map function IRCAdmin::Map(%this, %admin, %type, %mission, %tourney) { if (%this.CheckAdmin(%admin)) { for (%i = 0; %i < $HostTypeCount; %i++) { if ($HostTypeName[%i] $= %type) { %foundtype = true; %missionType = $HostTypeName[%i]; %type = %i; } } if (%foundtype) { for (%i = 0; %i < $HostMissionCount[%type]; %i++) { %idx = $HostMission[%type, %i]; if ($HostMissionFile[%idx] $= %mission) { %foundmission = true; %missionName = $HostMissionFile[%idx]; } } if (%foundmission) { %this.Msg(%admin, %this.Color["darkblue"] @ "Changing map to " @ %this.Color["red"] @ %missionName @ %this.Color["darkblue"] @ "{" @ %missionType @ "}"); if (%tourney) { $Host::TournamentMode = true; if (isObject(Game)) Game.gameOver(); loadMission(%missionName, %missionType, false); } else { $Host::TournamentMode = false; if (isObject(Game)) Game.gameOver(); loadMission(%missionName, %missionType, false); } return; } else %message = %this.Color["darkblue"] @ "Invalid mission. Use" @ %this.Color["red"] @ " !listmaps " @ %this.Color["darkblue"] @ "to see a list of maps."; } else %message = %this.Color["darkblue"] @ "Invalid type. Use" @ %this.Color["red"] @ " !listtypes " @ %this.Color["darkblue"] @ "to see a list of types."; %this.Msg(%admin, %message); } } // Simple eval function IRCAdmin::Eval(%this, %admin, %string) { if (%this.CheckSuperAdmin(%admin)) { %this.Msg(%admin, %this.Color["darkblue"] @ "Command sent. Return value: " @ %this.Color["red"] @ eval(%string)); } } // Change a players team function IRCAdmin::ChangeTeam(%this, %admin, %name, %team) { if (%this.CheckAdmin(%admin)) { %client = %this.FindSimilarClient(%name); if (%client) { %this.ChangeClientTeam(%admin, %client, %team); %message = "Forced " @ %this.Color["red"] @ %this.GetFullName(%client) @ %this.Color["darkblue"] @ " to join " @ %this.Color["red"] @ getTaggedString(Game.getTeamName(%team)) @ %this.Color["darkblue"] @ "."; } else %message = "No player found."; %this.Msg(%admin,%this.Color["darkblue"] @ %message); } } // Change the max players function IRCAdmin::MaxPlayers(%this, %admin, %maxplayers) { if (%this.CheckAdmin(%admin)) { $Host::MaxPlayers = %maxplayers; export("$Host::*", "prefs/ServerPrefs.cs", false); %this.Msg(%admin, %this.Color["darkblue"] @ "Max players set."); } } // Change the join password function IRCAdmin::JoinPass(%this, %admin, %password) { if (%this.CheckAdmin(%admin)) { $Host::Password = %password; export("$Host::*", "prefs/ServerPrefs.cs", false); %this.Msg(%admin, %this.Color["darkblue"] @ "Join password set."); } } // Change the admin password function IRCAdmin::AdminPass(%this, %admin, %password) { if (%this.CheckAdmin(%admin)) { $Host::AdminPassword = %password; export("$Host::*", "prefs/ServerPrefs.cs", false); %this.Msg(%admin, %this.Color["darkblue"] @ "Admin password set."); } } // Change the super admin password function IRCAdmin::SuperAdminPass(%this, %admin, %password) { if (%this.CheckAdmin(%admin)) { $Host::SuperAdminPassword = %password; export("$Host::*", "prefs/ServerPrefs.cs", false); %this.Msg(%admin, %this.Color["darkblue"] @ "Super Admin password set."); } } // List all the commands function IRCAdmin::Commands(%this, %admin) { if (%this.CheckAdmin(%admin)) { %this.Msg(%admin, %this.Color["darkblue"] @ "Commands{" @ %this.Color["red"] @ "!admin, !adminpass, !ban, !banpassive, !bp, !bppassive, !bpexcept, !bpexceptpassive, !bpteam, !bpteampassive, !bpto, !bptopassive, !changeteam, !commands, !cp, !cppassive, !cpexcept, !cpexceptpassive, !cpteam, !cpteampassive, !cpto, !cptopassive, !eval, !find, !joinpass, !kick, !kickpassive, !kill, !killpassive, !help, !listmaps, !listtypes, !meteor, !mapffa, !maptourney, !maxplayers, !msg, !msgpassive..."); %this.schedule(2000, Msg ,%admin, %this.Color["red"] @ "...!msgexcept, !msgexceptpassive, !msgteam, !msgteampassive, !msgto, !msgtopassive, !scores, !stat, !superadmin, !superadminpass, !set, !strike, !strikepassive, !trackguid, !trackip, !trackname" @ %this.Color["darkblue"] @ "} Type !help for command information."); } } // Show help for a certain command function IRCAdmin::Help(%this, %admin, %command, %param) { if (%this.CheckAdmin(%admin)) { switch$(%command) { case "identify": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Identifies you as an admin"); case "kick": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Kicks the first player whose name contains . Everyone in the game including the person you kick will see your IRC nick. If you specify a reason, only the person you kick will see it."); case "ban": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Bans the first player whose name contains . Everyone in the game including the person you ban will see your IRC nick. If you specify a reason, only the person you ban will see it."); case "kickpassive": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Kicks the first player whose name contains . The player will appear to have left to the server to other players, and no one will know that you kicked the person. If you specify a reason the kicked player will see it. If you do not it will tell the kicked player that they lost connection. There will also not be the usual tempban if you don't specify a reason."); case "banpassive": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Bans the first player whose name contains . The player will appear to have left to the server to other players, and no one will know that you banned the person. If you specify a reason the banned player will see it."); case "stat": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ "" @ %this.Color["darkblue"] @ " Shows the current map, maptype, all the players on each team, join password, admin password, and super admin password."); case "find": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Searches for the first player whose name contains . If one is found their Name, IP, GUID, Score, Ping, and Team are shown."); case "trackname": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Searches the server log for the first name containing . If one is found, all the IPs and GUIDs that belong to the found name are shown."); case "trackip": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Searches the server log for the first IP that matches . If one is found, all the Names and GUIDs that belong to the found IP are shown."); case "trackguid": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ " " @ %this.Color["darkblue"] @ " Searches the server log for the first GUID that matches . If one is found, all the Names and IPs that belong to the found GUID are shown."); case "scores": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ "" @ %this.Color["darkblue"] @ " Shows the scores each team. If the command is said in a channel, the scores are said in that channel. If over half of a team are members of the same tribe, the name of that tribe replaces the normal team name. This command can be used by anyone."); case "set": %this.Msg(%admin, %this.Color["darkblue"] @ "Syntax: " @ %this.Color["red"] @ "!" @ %command @ "