1: <?php
2:
3: namespace Budabot\User\Modules;
4:
5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
51: class GuildController {
52:
53: 54: 55: 56:
57: public $moduleName;
58:
59:
60: public $db;
61:
62:
63: public $chatBot;
64:
65:
66: public $settingManager;
67:
68:
69: public $buddylistManager;
70:
71:
72: public $playerManager;
73:
74:
75: public $guildManager;
76:
77:
78: public $text;
79:
80:
81: public $util;
82:
83:
84: public $altsController;
85:
86:
87: public $preferences;
88:
89:
90: public $logger;
91:
92: 93: 94:
95: public function setup() {
96: $this->db->loadSQLFile($this->moduleName, "org_members");
97:
98: $this->settingManager->add($this->moduleName, "max_logon_msg_size", "Maximum characters a logon message can have", "edit", "number", "200", "100;200;300;400", '', "mod");
99: $this->settingManager->add($this->moduleName, "max_logoff_msg_size", "Maximum characters a logoff message can have", "edit", "number", "200", "100;200;300;400", '', "mod");
100: $this->settingManager->add($this->moduleName, "first_and_last_alt_only", "Show logon/logoff for first/last alt only", "edit", "options", "0", "true;false", "1;0");
101:
102: $this->chatBot->guildmembers = array();
103: $sql = "SELECT o.name, IFNULL(p.guild_rank_id, 6) AS guild_rank_id
104: FROM org_members_<myname> o LEFT JOIN players p ON (o.name = p.name AND p.dimension = '<dim>' AND p.guild = '<myguild>')
105: WHERE mode != 'del'";
106: $data = $this->db->query($sql);
107: forEach ($data as $row) {
108: $this->chatBot->guildmembers[$row->name] = $row->guild_rank_id;
109: }
110: }
111:
112: 113: 114: 115:
116: public function logonMessageShowCommand($message, $channel, $sender, $sendto, $args) {
117: $logon_msg = $this->preferences->get($sender, 'logon_msg');
118:
119: if ($logon_msg === false || $logon_msg == '') {
120: $msg = "Your logon message has not been set.";
121: } else {
122: $msg = "{$sender} logon: {$logon_msg}";
123: }
124: $sendto->reply($msg);
125: }
126:
127: 128: 129: 130:
131: public function logonMessageSetCommand($message, $channel, $sender, $sendto, $args) {
132: $logon_msg = $args[1];
133:
134: if ($logon_msg == 'clear') {
135: $this->preferences->save($sender, 'logon_msg', '');
136: $msg = "Your logon message has been cleared.";
137: } else if (strlen($logon_msg) <= $this->settingManager->get('max_logon_msg_size')) {
138: $this->preferences->save($sender, 'logon_msg', $logon_msg);
139: $msg = "Your logon message has been set.";
140: } else {
141: $msg = "Your logon message is too large. Your logon message may contain a maximum of " . $this->settingManager->get('max_logon_msg_size') . " characters.";
142: }
143: $sendto->reply($msg);
144: }
145:
146: 147: 148: 149:
150: public function logoffMessageShowCommand($message, $channel, $sender, $sendto, $args) {
151: $logoff_msg = $this->preferences->get($sender, 'logoff_msg');
152:
153: if ($logoff_msg === false || $logoff_msg == '') {
154: $msg = "Your logoff message has not been set.";
155: } else {
156: $msg = "{$sender} logoff: {$logoff_msg}";
157: }
158: $sendto->reply($msg);
159: }
160:
161: 162: 163: 164:
165: public function logoffMessageSetCommand($message, $channel, $sender, $sendto, $args) {
166: $logoff_msg = $args[1];
167:
168: if ($logoff_msg == 'clear') {
169: $this->preferences->save($sender, 'logoff_msg', '');
170: $msg = "Your logoff message has been cleared.";
171: } else if (strlen($logoff_msg) <= $this->settingManager->get('max_logoff_msg_size')) {
172: $this->preferences->save($sender, 'logoff_msg', $logoff_msg);
173: $msg = "Your logoff message has been set.";
174: } else {
175: $msg = "Your logoff message is too large. Your logoff message may contain a maximum of " . $this->settingManager->get('max_logoff_msg_size') . " characters.";
176: }
177: $sendto->reply($msg);
178: }
179:
180: 181: 182: 183:
184: public function lastseenCommand($message, $channel, $sender, $sendto, $args) {
185: $name = ucfirst(strtolower($args[1]));
186: $uid = $this->chatBot->get_uid($name);
187: if (!$uid) {
188: $msg = "Character <highlight>$name<end> does not exist.";
189: } else {
190: $altInfo = $this->altsController->getAltInfo($name);
191: $onlineAlts = $altInfo->getOnlineAlts();
192:
193: $blob = "";
194: forEach ($onlineAlts as $onlineAlt) {
195: $blob .= "<highlight>$onlineAlt<end> is currently online.\n";
196: }
197:
198: $namesSql = implode(",", array_map(function($alt) { return "'$alt'";}, $altInfo->getAllAlts()));
199: $data = $this->db->query("SELECT * FROM org_members_<myname> WHERE `name` IN ($namesSql) AND `mode` != 'del' ORDER BY logged_off DESC");
200:
201: forEach ($data as $row) {
202: if (in_array($row->name, $onlineAlts)) {
203:
204: continue;
205: } else if ($row->logged_off == 0) {
206: $blob .= "<highlight>$row->name<end> has never logged on.\n";
207: } else {
208: $blob .= "<highlight>$row->name<end> last seen at " . $this->util->date($row->logged_off) . ".\n";
209: }
210: }
211:
212: if (count($data) == 0) {
213: $msg .= "Character <highlight>$name<end> is not a member of the org.";
214: } else {
215: $msg = $this->text->makeBlob("Last Seen Info for $altInfo->main", $blob);
216: }
217: }
218:
219: $sendto->reply($msg);
220: }
221:
222: 223: 224: 225:
226: public function recentseenCommand($message, $channel, $sender, $sendto, $args) {
227: if (!$this->isGuildBot()) {
228: $sendto->reply("The bot must be in an org.");
229: return;
230: }
231:
232: $time = $this->util->parseTime($args[1]);
233: if ($time < 1) {
234: $msg = "You must enter a valid time parameter.";
235: $sendto->reply($msg);
236: return;
237: }
238:
239: $timeString = $this->util->unixtimeToReadable($time, false);
240: $time = time() - $time;
241:
242: $data = $this->db->query("SELECT case when a.main is null then o.name else a.main end as main ,o.logged_off,o.name FROM org_members_<myname> o LEFT JOIN alts a ON o.name = a.alt WHERE `mode` != 'del' AND `logged_off` > ? ORDER BY 1, o.logged_off desc, o.name", $time);
243:
244: if (count($data) == 0) {
245: $sendto->reply("No members recorded.");
246: return;
247: }
248:
249: $numinactive = 0;
250: $highlight = 0;
251:
252: $blob = "Org members who have logged off within the last <highlight>{$timeString}<end>.\n\n";
253:
254: $prevtoon = '';
255: forEach ($data as $row) {
256: if ($row->main != $prevtoon) {
257: $prevtoon = $row->main;
258: $numrecentcount++;
259: $alts = $this->text->makeChatcmd("Alts", "/tell <myname> alts {$row->main}");
260: $logged = $row->logged_off;
261: $lasttoon = $row->name;
262:
263: $character = "<pagebreak>" . $row->main . " [{$alts}]\nLast seen as [$lasttoon] on " . $this->util->date($logged) . "\n\n";
264: if ($highlight == 1) {
265: $blob .= "<highlight>$character<end>";
266: $highlight = 0;
267: } else {
268: $blob .= $character;
269: $highlight = 1;
270: }
271: }
272: }
273: $msg = $this->text->makeBlob("$numrecentcount recently seen org members", $blob);
274: $sendto->reply($msg);
275: }
276:
277: 278: 279: 280:
281: public function notifyAddCommand($message, $channel, $sender, $sendto, $args) {
282: $name = ucfirst(strtolower($args[2]));
283: $uid = $this->chatBot->get_uid($name);
284:
285: if (!$uid) {
286: $msg = "<highlight>{$name}<end> does not exist.";
287: $sendto->reply($msg);
288: return;
289: }
290:
291: $row = $this->db->queryRow("SELECT mode FROM org_members_<myname> WHERE `name` = ?", $name);
292:
293: if ($row !== null && $row->mode != "del") {
294: $msg = "<highlight>{$name}<end> is already on the Notify list.";
295: } else {
296: if ($row === null) {
297: $this->db->exec("INSERT INTO org_members_<myname> (`name`, `mode`) VALUES (?, 'add')", $name);
298: } else {
299: $this->db->exec("UPDATE org_members_<myname> SET `mode` = 'add' WHERE `name` = ?", $name);
300: }
301:
302: if ($this->buddylistManager->isOnline($name) == 1) {
303: $this->db->exec("INSERT INTO online (`name`, `channel`, `channel_type`, `added_by`, `dt`) VALUES (?, '<myguild>', 'guild', '<myname>', ?)", $name, time());
304: }
305: $this->buddylistManager->add($name, 'org');
306: $this->chatBot->guildmembers[$name] = 6;
307: $msg = "<highlight>{$name}<end> has been added to the Notify list.";
308: }
309:
310: $sendto->reply($msg);
311: }
312:
313: 314: 315: 316:
317: public function notifyRemoveCommand($message, $channel, $sender, $sendto, $args) {
318: $name = ucfirst(strtolower($args[2]));
319: $uid = $this->chatBot->get_uid($name);
320:
321: if (!$uid) {
322: $msg = "<highlight>{$name}<end> does not exist.";
323: $sendto->reply($msg);
324: return;
325: }
326:
327: $row = $this->db->queryRow("SELECT mode FROM org_members_<myname> WHERE `name` = ?", $name);
328:
329: if ($row === null) {
330: $msg = "<highlight>{$name}<end> is not on the guild roster.";
331: } else if ($row->mode == "del") {
332: $msg = "<highlight>{$name}<end> has already been removed from the Notify list.";
333: } else {
334: $this->db->exec("UPDATE org_members_<myname> SET `mode` = 'del' WHERE `name` = ?", $name);
335: $this->db->exec("DELETE FROM online WHERE `name` = ? AND `channel_type` = 'guild' AND added_by = '<myname>'", $name);
336: $this->buddylistManager->remove($name, 'org');
337: unset($this->chatBot->guildmembers[$name]);
338: $msg = "Removed <highlight>{$name}<end> from the Notify list.";
339: }
340:
341: $sendto->reply($msg);
342: }
343:
344: 345: 346: 347:
348: public function updateorgCommand($message, $channel, $sender, $sendto, $args) {
349: $force_update = true;
350: $sendto->reply("Starting Roster update");
351: $this->updateOrgRoster();
352: $sendto->reply("Finished Roster update");
353: }
354:
355: public function updateOrgRoster() {
356: if ($this->isGuildBot()) {
357: $this->logger->log('INFO', "Starting Roster update");
358:
359:
360: $org = $this->guildManager->getById($this->chatBot->vars["my_guild_id"], $this->chatBot->vars["dimension"], true);
361:
362:
363: if ($org === null) {
364: $this->logger->log('ERROR', "Error downloading the guild roster xml file");
365: return;
366: }
367:
368: if (count($org->members) == 0) {
369: $this->logger->log('ERROR', "Guild xml file has no members! Aborting roster update.");
370: return;
371: }
372:
373:
374: $data = $this->db->query("SELECT * FROM org_members_<myname>");
375: if (count($data) == 0 && (count($org->members) > 0)) {
376: $restart = true;
377: } else {
378: $restart = false;
379: forEach ($data as $row) {
380: $dbentrys[$row->name]["name"] = $row->name;
381: $dbentrys[$row->name]["mode"] = $row->mode;
382: }
383: }
384:
385: $this->chatBot->ready = false;
386:
387: $this->db->beginTransaction();
388:
389:
390: forEach ($org->members as $member) {
391:
392: if (strtolower($member->name) == strtolower($this->chatBot->vars["name"])) {
393: continue;
394: }
395:
396:
397: if (isset($dbentrys[$member->name])) {
398: if ($dbentrys[$member->name]["mode"] == "del") {
399:
400: $this->buddylistManager->remove($member->name, 'org');
401: unset($this->chatBot->guildmembers[$name]);
402: } else {
403:
404: $this->buddylistManager->add($member->name, 'org');
405: $this->chatBot->guildmembers[$member->name] = $member->guild_rank_id;
406:
407:
408: if ($dbentrys[$member->name]["mode"] == "add") {
409: $this->db->exec("UPDATE org_members_<myname> SET `mode` = 'org' WHERE `name` = ?", $member->name);
410: }
411: }
412:
413: } else {
414:
415: $this->buddylistManager->add($member->name, 'org');
416: $this->chatBot->guildmembers[$member->name] = $member->guild_rank_id;
417:
418: $this->db->exec("INSERT INTO org_members_<myname> (`name`, `mode`) VALUES (?, 'org')", $member->name);
419: }
420: unset($dbentrys[$member->name]);
421: }
422:
423: $this->db->commit();
424:
425:
426: forEach ($dbentrys as $buddy) {
427: if ($buddy['mode'] != 'add') {
428: $this->db->exec("DELETE FROM online WHERE `name` = ? AND `channel_type` = 'guild' AND added_by = '<myname>'", $buddy['name']);
429: $this->db->exec("DELETE FROM org_members_<myname> WHERE `name` = ?", $buddy['name']);
430: $this->buddylistManager->remove($buddy['name'], 'org');
431: unset($this->chatBot->guildmembers[$buddy['name']]);
432: }
433: }
434:
435: $this->logger->log('INFO', "Finished Roster update");
436:
437: if ($restart == true) {
438: $this->chatBot->sendGuild("Guild roster has been loaded for the first time. Restarting...");
439:
440: $this->logger->log('INFO', "The bot is restarting");
441:
442: sleep(5);
443:
444:
445:
446: die();
447: }
448: }
449: }
450:
451: 452: 453: 454:
455: public function downloadOrgRosterEvent($eventObj) {
456: $this->updateOrgRoster();
457: }
458:
459: 460: 461: 462:
463: public function autoNotifyOrgMembersEvent($eventObj) {
464: $message = $eventObj->message;
465: if (preg_match("/^(.+) invited (.+) to your organization.$/", $message, $arr)) {
466: $name = ucfirst(strtolower($arr[2]));
467:
468: if ($this->buddylistManager->isOnline("") == 1) {
469: $this->db->exec("INSERT INTO online (`name`, `channel`, `channel_type`, `added_by`, `dt`) VALUES (?, '<myguild>', 'guild', '<myname>', ?)", $name, time());
470: }
471:
472: $row = $this->db->queryRow("SELECT * FROM org_members_<myname> WHERE `name` = ?", $name);
473: if ($row !== null) {
474: $this->db->exec("UPDATE org_members_<myname> SET `mode` = 'add' WHERE `name` = ?", $name);
475: $this->buddylistManager->add($name, 'org');
476: $this->chatBot->guildmembers[$name] = 6;
477: } else {
478: $this->db->exec("INSERT INTO org_members_<myname> (`mode`, `name`) VALUES ('add', ?)", $name);
479: $this->buddylistManager->add($name, 'org');
480: $this->chatBot->guildmembers[$name] = 6;
481: }
482:
483:
484: $this->playerManager->getByName($name);
485: } else if (preg_match("/^(.+) kicked (.+) from your organization.$/", $message, $arr) || preg_match("/^(.+) removed inactive character (.+) from your organization.$/", $message, $arr)) {
486: $name = ucfirst(strtolower($arr[2]));
487:
488: $this->db->exec("UPDATE org_members_<myname> SET `mode` = 'del' WHERE `name` = ?", $name);
489: $this->db->exec("DELETE FROM online WHERE `name` = ? AND `channel_type` = 'guild' AND added_by = '<myname>'", $name);
490:
491: unset($this->chatBot->guildmembers[$name]);
492: $this->buddylistManager->remove($name, 'org');
493: } else if (preg_match("/^(.+) just left your organization.$/", $message, $arr) || preg_match("/^(.+) kicked from organization \\(alignment changed\\).$/", $message, $arr)) {
494: $name = ucfirst(strtolower($arr[1]));
495:
496: $this->db->exec("UPDATE org_members_<myname> SET `mode` = 'del' WHERE `name` = ?", $name);
497: $this->db->exec("DELETE FROM online WHERE `name` = ? AND `channel_type` = 'guild' AND added_by = '<myname>'", $name);
498:
499: unset($this->chatBot->guildmembers[$name]);
500: $this->buddylistManager->remove($name, 'org');
501: }
502: }
503:
504: 505: 506: 507:
508: public function orgMemberLogonMessageEvent($eventObj) {
509: $sender = $eventObj->sender;
510: if (isset($this->chatBot->guildmembers[$sender]) && $this->chatBot->isReady()) {
511: if ($this->settingManager->get('first_and_last_alt_only') == 1) {
512:
513: $altInfo = $this->altsController->getAltInfo($sender);
514: if (count($altInfo->getOnlineAlts()) > 1) {
515: return;
516: }
517: }
518:
519: $whois = $this->playerManager->getByName($sender);
520:
521: $msg = '';
522: if ($whois === null) {
523: $msg = "$sender logged on.";
524: } else {
525: $msg = $this->playerManager->getInfo($whois);
526:
527: $msg .= " logged on.";
528:
529: $altInfo = $this->altsController->getAltInfo($sender);
530: if (count($altInfo->alts) > 0) {
531: $msg .= " " . $altInfo->getAltsBlob(false, true);
532: }
533: }
534:
535: $logon_msg = $this->preferences->get($sender, 'logon_msg');
536: if ($logon_msg !== false && $logon_msg != '') {
537: $msg .= " - " . $logon_msg;
538: }
539:
540: $this->chatBot->sendGuild($msg, true);
541:
542:
543: if ($this->settingManager->get("guest_relay") == 1) {
544: $this->chatBot->sendPrivate($msg, true);
545: }
546: }
547: }
548:
549: 550: 551: 552:
553: public function orgMemberLogoffMessageEvent($eventObj) {
554: $sender = $eventObj->sender;
555: if (isset($this->chatBot->guildmembers[$sender]) && $this->chatBot->isReady()) {
556: if ($this->settingManager->get('first_and_last_alt_only') == 1) {
557:
558: $altInfo = $this->altsController->getAltInfo($sender);
559: if (count($altInfo->getOnlineAlts()) > 0) {
560: return;
561: }
562: }
563:
564: $msg = "$sender logged off.";
565: $logoff_msg = $this->preferences->get($sender, 'logoff_msg');
566: if ($logoff_msg !== false && $logoff_msg != '') {
567: $msg .= " - " . $logoff_msg;
568: }
569:
570: $this->chatBot->sendGuild($msg, true);
571:
572:
573: if ($this->settingManager->get("guest_relay") == 1) {
574: $this->chatBot->sendPrivate($msg, true);
575: }
576: }
577: }
578:
579: 580: 581: 582:
583: public function orgMemberLogoffRecordEvent($eventObj) {
584: $sender = $eventObj->sender;
585: if (isset($this->chatBot->guildmembers[$sender]) && $this->chatBot->isReady()) {
586: $this->db->exec("UPDATE org_members_<myname> SET `logged_off` = ? WHERE `name` = ?", time(), $sender);
587: }
588: }
589:
590: public function isGuildBot() {
591: return !empty($this->chatBot->vars["my_guild"]) && !empty($this->chatBot->vars["my_guild_id"]);
592: }
593:
594: 595: 596: 597:
598: public function verifyOrgNameEvent($eventObj) {
599: if (!empty($this->chatBot->vars["my_guild"])) {
600: if (empty($this->chatBot->vars["my_guild_id"])) {
601: $this->logger->log('warn', "Org name '{$this->chatBot->vars["my_guild"]}' specified, but bot does not appear to belong to an org");
602: } else {
603: $gid = $this->getOrgChannelIdByOrgId($this->chatBot->vars["my_guild_id"]);
604: $orgChannel = $this->chatBot->gid[$gid];
605: if ($orgChannel != "Clan (name unknown)" && $orgChannel != $this->chatBot->vars["my_guild"]) {
606: $this->logger->log('warn', "Org name '{$this->chatBot->vars["my_guild"]}' specified, but bot belongs to org '$orgChannel'");
607: }
608: }
609: }
610: }
611:
612: public function getOrgChannelIdByOrgId($orgId) {
613: forEach ($this->chatBot->grp as $gid => $status) {
614: $string = unpack("N", substr($gid, 1));
615: if (ord(substr($gid, 0, 1)) == 3 && $string[1] == $orgId) {
616: return $gid;
617: }
618: }
619: return null;
620: }
621: }
622:
623: