/addons/sourcemod/scripting/SourceIRC/sourceirc-ticket.sp

https://bitbucket.org/kimoto/sushi · Unknown · 258 lines · 225 code · 33 blank · 0 comment · 0 complexity · 2a272e6dfe251029fb05778a62badeba MD5 · raw file

  1. /*
  2. This file is part of SourceIRC.
  3. SourceIRC is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. SourceIRC is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with SourceIRC. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <sdktools>
  15. #undef REQUIRE_PLUGIN
  16. #include <sourceirc>
  17. #pragma semicolon 1
  18. new Float:SprayLocation[MAXPLAYERS+1][3];
  19. new String:ReportString[MAXPLAYERS+1][512];
  20. new Handle:kv;
  21. public Plugin:myinfo = {
  22. name = "SourceIRC -> Ticket",
  23. author = "Azelphur",
  24. description = "Adds a report command in game for players to report problems to staff in an IRC channel",
  25. version = IRC_VERSION,
  26. url = "http://Azelphur.com/project/sourceirc"
  27. };
  28. public OnPluginStart() {
  29. LoadTranslations("common.phrases");
  30. RegConsoleCmd("report", Command_Support);
  31. RegConsoleCmd("reply", Command_Reply);
  32. AddTempEntHook("Player Decal", PlayerSpray);
  33. kv = CreateKeyValues("SourceIRC");
  34. decl String:file[512];
  35. BuildPath(Path_SM, file, sizeof(file), "configs/sourceirc.cfg");
  36. FileToKeyValues(kv, file);
  37. }
  38. public OnAllPluginsLoaded() {
  39. if (LibraryExists("sourceirc"))
  40. IRC_Loaded();
  41. }
  42. public OnLibraryAdded(const String:name[]) {
  43. if (StrEqual(name, "sourceirc"))
  44. IRC_Loaded();
  45. }
  46. IRC_Loaded() {
  47. IRC_CleanUp(); // Call IRC_CleanUp as this function can be called more than once.
  48. IRC_RegAdminCmd("to", Command_To, ADMFLAG_CHAT, "to <name|#userid> <text> - Send a message to a player");
  49. }
  50. public Action:Command_Reply(client, args) {
  51. decl String:Args[256], String:name[64], String:auth[64];
  52. GetCmdArgString(Args, sizeof(Args));
  53. if (StrEqual(Args, ""))
  54. return Plugin_Handled;
  55. GetClientName(client, name, sizeof(name));
  56. GetClientAuthString(client, auth, sizeof(auth));
  57. IRC_MsgFlaggedChannels("ticket", "%s (%s) : %s", name, auth, Args);
  58. PrintToChat(client, "To ADMIN : %s", Args);
  59. return Plugin_Handled;
  60. }
  61. public Action:Command_To(const String:nick[], args) {
  62. decl String:destination[64], String:text[IRC_MAXLEN];
  63. IRC_GetCmdArgString(text, sizeof(text));
  64. new startpos = BreakString(text, destination, sizeof(destination));
  65. new target = FindTarget(0, destination, true, false);
  66. if (target != -1) {
  67. PrintToChat(target, "\x01[\x04IRC\x01] \x03(ADMIN) %s\x01 : %s", nick, text[startpos]);
  68. }
  69. else {
  70. IRC_ReplyToCommand(nick, "Unable to find %s", destination);
  71. }
  72. return Plugin_Handled;
  73. }
  74. public Action:PlayerSpray(const String:te_name[],const clients[],client_count,Float:delay) {
  75. new client=TE_ReadNum("m_nPlayer");
  76. TE_ReadVector("m_vecOrigin", SprayLocation[client]);
  77. }
  78. TraceSpray(client) {
  79. new Float:pos[3];
  80. if(GetPlayerEye(client, pos) >= 1){
  81. new Float:MaxDis = 50.0;
  82. for(new i = 1; i<= MAXPLAYERS; i++) {
  83. if(GetVectorDistance(pos, SprayLocation[i]) <= MaxDis)
  84. return i;
  85. }
  86. }
  87. return 0;
  88. }
  89. stock GetPlayerEye(client, Float:pos[3]) {
  90. new Float:vAngles[3], Float:vOrigin[3];
  91. GetClientEyePosition(client,vOrigin);
  92. GetClientEyeAngles(client, vAngles);
  93. new Handle:trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SHOT, RayType_Infinite, TraceEntityFilterPlayer);
  94. if(TR_DidHit(trace)) {
  95. TR_GetEndPosition(pos, trace);
  96. if(GetVectorDistance(pos, vOrigin) <= 128.0)
  97. return 2;
  98. return 1;
  99. }
  100. return 0;
  101. }
  102. public bool:TraceEntityFilterPlayer(entity, contentsMask) {
  103. new String:classname[64];
  104. GetEntityNetClass(entity, classname, 64);
  105. return !StrEqual(classname, "CTFPlayer");
  106. }
  107. public Action:Command_Support(client, args) {
  108. new Handle:hMenu=CreateMenu(MenuHandler_Report);
  109. SetMenuTitle(hMenu,"What do you want to report for?");
  110. if (!KvJumpToKey(kv, "Ticket")) return;
  111. if (!KvJumpToKey(kv, "Menu")) return;
  112. if (!KvGotoFirstSubKey(kv, false)) return;
  113. decl String:key[64], String:value[64];
  114. do
  115. {
  116. KvGetSectionName(kv, key, sizeof(key));
  117. KvGetString(kv, NULL_STRING, value, sizeof(value));
  118. AddMenuItem(hMenu, key, value);
  119. } while (KvGotoNextKey(kv, false));
  120. KvRewind(kv);
  121. DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
  122. }
  123. public MenuHandler_Report(Handle:hMenu, MenuAction:action, param1, param2) {
  124. if(action==MenuAction_Select) {
  125. GetMenuItem(hMenu, param2, ReportString[param1], sizeof(ReportString[]));
  126. if (StrEqual(ReportString[param1], "{Special:Spray}"))
  127. SprayMenu(param1);
  128. else
  129. ShowPlayerList(param1);
  130. }
  131. }
  132. SprayMenu(client) {
  133. new Handle:hMenu = CreateMenu(MenuHandler_SprayMenu);
  134. SetMenuTitle(hMenu, "Aim at the spray you wish to report, then press ok.");
  135. AddMenuItem(hMenu, "Ok", "Ok");
  136. SetMenuExitBackButton(hMenu, true);
  137. DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
  138. }
  139. public MenuHandler_SprayMenu(Handle:menu, MenuAction:action, param1, param2)
  140. {
  141. if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) {
  142. Command_Support(param1, 0);
  143. }
  144. else if (action == MenuAction_Select) {
  145. new target = TraceSpray(param1);
  146. if (!target) {
  147. PrintToChat(param1, "No spray found where you are looking, try getting closer!");
  148. SprayMenu(param1);
  149. }
  150. else {
  151. decl String:decalfile[256];
  152. GetPlayerDecalFile(target, decalfile, sizeof(decalfile));
  153. decl String:sprayurl[128];
  154. sprayurl[0] = '\x00';
  155. Format(ReportString[param1], sizeof(ReportString[]), "Bad spray");
  156. if ((KvJumpToKey(kv, "Ticket")) && (KvJumpToKey(kv, "Settings"))) {
  157. KvGetString(kv, "spray_url", sprayurl, sizeof(sprayurl), "");
  158. if (!StrEqual(sprayurl, "")) {
  159. ReplaceString(sprayurl, sizeof(sprayurl), "{SPRAY}", decalfile);
  160. StrCat(ReportString[param1], sizeof(ReportString), " ");
  161. StrCat(ReportString[param1], sizeof(ReportString), sprayurl);
  162. }
  163. }
  164. KvRewind(kv);
  165. Report(param1, target, ReportString[param1]);
  166. }
  167. }
  168. }
  169. ShowPlayerList(client) {
  170. new Handle:hMenu = CreateMenu(MenuHandler_PlayerList);
  171. decl String:title[256];
  172. Format(title, sizeof(title), "Who do you want to report for %s", ReportString[client]);
  173. SetMenuTitle(hMenu, title);
  174. SetMenuExitBackButton(hMenu, true);
  175. new maxclients = GetMaxClients();
  176. decl String:disp[64], String:info[64];
  177. for (new i = 1; i <= maxclients; i++) {
  178. if (IsClientConnected(i) && !IsFakeClient(i)) {
  179. GetClientName(i, disp, sizeof(disp));
  180. IntToString(GetClientUserId(i), info, sizeof(info));
  181. AddMenuItem(hMenu, info, disp);
  182. }
  183. }
  184. DisplayMenu(hMenu, client, MENU_TIME_FOREVER);
  185. }
  186. public MenuHandler_PlayerList(Handle:menu, MenuAction:action, param1, param2)
  187. {
  188. if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) {
  189. Command_Support(param1, 0);
  190. }
  191. else if (action == MenuAction_Select) {
  192. decl String:info[32];
  193. GetMenuItem(menu, param2, info, sizeof(info));
  194. new client = GetClientOfUserId(StringToInt(info));
  195. if (!client) {
  196. PrintToChat(param1, "Player disconnected, sorry!");
  197. }
  198. else {
  199. Report(param1, client, ReportString[param1]);
  200. }
  201. }
  202. }
  203. Report(client, target, String:info[]) {
  204. decl String:name[64], String:auth[64], String:targetname[64], String:targetauth[64], String:mynick[64];
  205. GetClientName(client, name, sizeof(name));
  206. GetClientAuthString(client, auth, sizeof(auth));
  207. GetClientName(target, targetname, sizeof(targetname));
  208. GetClientAuthString(target, targetauth, sizeof(targetauth));
  209. IRC_GetNick(mynick, sizeof(mynick));
  210. if ((KvJumpToKey(kv, "Ticket")) && (KvJumpToKey(kv, "Settings"))) {
  211. decl String:custom_msg[IRC_MAXLEN];
  212. KvGetString(kv, "custom_msg", custom_msg, sizeof(custom_msg), "");
  213. if (!StrEqual(custom_msg, "")) {
  214. IRC_MsgFlaggedChannels("ticket", custom_msg);
  215. }
  216. }
  217. KvRewind(kv);
  218. IRC_MsgFlaggedChannels("ticket", "%s (%s) has reported %s (%s) for %s", name, auth, targetname, targetauth, info);
  219. IRC_MsgFlaggedChannels("ticket", "use %s to #%d <text> - To reply", mynick, GetClientUserId(client));
  220. PrintToChat(client, "\x01Your report has been sent. Type \x04/reply your text here\x01 to chat with the admins.");
  221. }
  222. public OnPluginEnd() {
  223. IRC_CleanUp();
  224. }
  225. // http://bit.ly/defcon