Advertisement
Guest User

Untitled

a guest
Jun 26th, 2016
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 156.06 KB | None | 0 0
  1. // -------------------------------------- //
  2. // EVIDENCE by domino54 //
  3. // script version: 2.0 @2016-02-07 //
  4. // -------------------------------------- //
  5.  
  6. /**
  7. * INSTALLATION GUIDE
  8. * 1. Rename file to "Chat.Script.txt".
  9. * 2. Place this file in folder: "(user data directory)/Media/Manialinks/Common/Chat/Chat.Script.txt".
  10. * 3. Restart game to apply changes.
  11. */
  12.  
  13. #RequireContext CManiaplanetPlugin
  14.  
  15. #Const ScriptName "Evidence.Script.txt"
  16. #Const ScriptVersion "2016-02-07"
  17. #Const ScriptVersionNb "2.0"
  18.  
  19. #Include "MathLib" as ML
  20. #Include "TextLib" as TL
  21.  
  22. /*
  23.  
  24. CHANGELOG
  25.  
  26. Additions:
  27. + Evidence Global Chat: text with everyone using Evidence in a single group.
  28. + Dynamic status: option to set dynamic status depending on what you're currently doing.
  29. + Heavy design tweaks.
  30. + Buddy Invitations tab with list of all buddy requests and option to invite players.
  31. + Settings tab with various options of the chat plugin.
  32. + Group Chat can be now secured with password defined in settings tab.
  33. + Some extra Group Chat formatted messages commands.
  34. + Notifications about incoming updates.
  35.  
  36. Tweaks:
  37. ~ Extremely optimized plugin code.
  38. ~ Buttons on the buddies cards are now displayed only when chat is in corresponding mode.
  39. ~ Commands sent to other buddies now won't be shown.
  40. ~ Command used to leave group is now called "quit", instead "leave".
  41. ~ Group Chat will now find names from logins with even less than 4 specified characters.
  42.  
  43. Removed features:
  44. - Server mode and players amount is no longer available to check.
  45. - Server name is no longer visible in Group Chat mode.
  46. */
  47.  
  48. // ---------------------------------- //
  49. // Constants
  50. // ---------------------------------- //
  51. #Const C_ImgBase "file://Media/Manialinks/Common/Chat/"
  52.  
  53. /// Available statuses depending on user presence Id
  54. #Const C_UserPresenceStatus [_("Offline"), _("Available"), _("Away"), _("Busy"), _("Wanna talk!"), _("Snooze")]
  55.  
  56. /// Words to avoid in context status
  57. #Const C_ContextAvoidInTitle ["TrackMania ", "ShootMania "]
  58.  
  59. /// Prosences on which context status will be applied
  60. #Const C_ContextStatusPresences [1, 3]
  61.  
  62. /// Available statuses depending on active context
  63. #Const C_ContextStatusText [
  64. ::EContext::MenuManiaPlanet => _("In ManiaPlanet main menu"),
  65. ::EContext::MenuManiaTitleMain => _("In $<%1$> main menu"),
  66. ::EContext::MenuCustom => _("In $<%1$> custom menu"),
  67. ::EContext::MenuSolo => _("In $<%1$> solo menu"),
  68. ::EContext::MenuLocal => _("In $<%1$> multiplayer menu"),
  69. ::EContext::MenuEditors => _("In $<%1$> editors menu"),
  70. ::EContext::MenuProfile => _("In $<%1$> profile menu"),
  71. ::EContext::Solo => _("Playing $<%1$> solo"),
  72. ::EContext::Multi => _("Playing $<%1$> multiplayer"),
  73. ::EContext::EditorTrack => _("Editing a map in $<%1$>"),
  74. ::EContext::EditorPainter => _("Painting a car in $<%1$>"),
  75. ::EContext::EditorMediaTracker => _("Editing a replay in $<%1$>")
  76. ]
  77.  
  78. // ---------------------------------- //
  79. // Group Chat settings
  80. // ---------------------------------- //
  81. #Const C_GroupOfflineRemovalDelay 5000 ///< Delay before removing offline buddies upon chat startup
  82.  
  83. /// Group Chat messages format
  84. #Const C_GroupFormatMessage "$FF0"
  85. #Const C_GroupFormatSuccess "$0F0"
  86. #Const C_GroupFormatInfo "$6BF"
  87. #Const C_GroupFormatPrivate "$F80"
  88. #Const C_GroupFormatError "$F00Error: "
  89.  
  90. /// Required permissions level to perform a command
  91. #Const C_GroupCommandPermissionsLevels [
  92. "kick" => 1, "mute" => 1, "unmute" => 1, "ban" => 1, "unban" => 1, "addop" => 2, "removeop" => 2
  93. ]
  94.  
  95. /// Group Chat formatted messages
  96. #Const C_ChatMessageCommands [
  97. "hi" => "Hello", "bb" => "Bye", "re" => "Returned", "wb" => "Welcome back",
  98. "afk" => "Away from keyboard", "gtg" => "Got to go", "brb" => "Be right back",
  99. "gg" => "Good game", "gga" => "Good game all", "gj" => "Good job",
  100. "n1" => "Nice one", "ns" => "Nice shoot", "nt" => "Nice time", "ty" => "Thank you",
  101. "gl" => "Good luck", "hf" => "Have fun", "glhf" => "Goold luck and have fun",
  102. "wp" => "Well played", "ggwp" => "Good game, well played",
  103. "gr8" => "Great", "w8" => "Wait", "lol" => "Loo0ool", "lool" => "Looo00oool",
  104. "54" => "I <3 Domino", "gu" => "Guerried", "grt" => "Guerritos",
  105. "flo" => "Florenziusted", "nu" => "Nurpsen", "owz" => "Owzom", "wow" => "WOOW"
  106. ]
  107.  
  108. /// Group Chat formatted messages, that can be used with login
  109. #Const C_ChatMessageWithLogin [
  110. "hi", "bb", "wb", "flo", "gg", "gj", "n1", "ns", "nt", "ty", "lol", "lool",
  111. "gl", "hf", "glhf", "wp", "ggwp", "gu", "gr8", "w8", "owz", "wow"
  112. ]
  113.  
  114. // ---------------------------------- //
  115. /** Commands help description
  116. * [required parameter] <optional parameter>
  117. */
  118. #Const C_GroupCommandsHelp [
  119. "help" => "You seem to be really desperate.",
  120. "join" => "/join - Join the Group Chat server.",
  121. "quit" => "/quit - Leave the Group Chat server.",
  122. "list" => "/list <op|mute|ban|nf|logins> - Display list with logins of specified users on the server.",
  123. "me" => "/me [message] - Describe what are you currently doing.",
  124. "kick" => "/kick [login] - Disconnect specified user from the server.",
  125. "mute" => "/mute [login] - Mute specified user. Messages of muted users aren't shown.",
  126. "unmute" => "/unmute [login] - Remove mute penalty from specified user.",
  127. "ban" => "/ban [login] - Ban specified user from the Group Chat.",
  128. "unban" => "/unmute [login] - Remove ban penalty from specified user.",
  129. "addop" => "/addop [login] - Give specified user operator rights.",
  130. "removeop" => "/removeop [login] - Remove operator rights from specified user.",
  131. "noformat" => "/noformat <0|1> - Remove formatting from nicknames to save messages length.",
  132. "pm" => "/pm [login] [message] - Send private message to a specified user.",
  133. "pmr" => "/pmr [message] - Reply to the latest received private message.",
  134. "core" => "/core - Returns name and version of the Group Chat script file.",
  135. "rq" => "/rq - Leave the Group Chat server. With anger.",
  136. "bm" => "/bm - Kick yourself from the Group Chat, if you really want.",
  137. "/chatmsg" => "<login> - Shortcut displaying formatted message in chat."
  138. ]
  139.  
  140. // ---------------------------------- //
  141. // Global Chat settings
  142. // ---------------------------------- //
  143. #Const C_GlobalChatServerURL "http://2.3.49.155/JavaWeb/"
  144. #Const C_GlobalChatServerMethods ["GET_UID", "GET_USER_LIST", "GET_MSG", "REFRESH", "SET_STATUS", "SEND_MSG"]
  145. #Const C_GlobalChatGetUIDTimeout 10000
  146. #Const C_GlobalChatRequestInterval [
  147. "GET_UID" => 2000,
  148. "GET_USER_LIST" => 7500,
  149. "GET_MSG" => 1000,
  150. "REFRESH" => 5000,
  151. "SET_STATUS" => 7500
  152. ]
  153.  
  154. // ---------------------------------- //
  155. // Global variables
  156. // ---------------------------------- //
  157. declare Integer[] G_GlobalChat_ReceivedMessages; ///< Messages Ids received in Global Chat mode
  158. declare Boolean G_GlobalChat_ConnectionError; ///< True, if local user is not present in users list
  159.  
  160. // ---------------------------------- //
  161. // Main
  162. // ---------------------------------- //
  163. ***Main***
  164. ***
  165. // ---------------------------------- //
  166. // Connect to the ManiaPlanet Chat server
  167. BuddiesManager.DesiredConnectionStatus = CBuddiesManager::EDesiredConnectionStatus::Online;
  168. wait(BuddiesManager.CurrentConnectionStatus == CBuddiesManager::EConnectionStatus::Online);
  169.  
  170. // ---------------------------------- //
  171. // Layer of the plugin icon
  172. declare IconLayer <=> UILayerCreate();
  173. IconLayer.AttachId = "IconLayer";
  174. IconLayer.ManialinkPage = CreateManialinkPluginIcon();
  175. IconLayer.Type = CUILayer::EUILayerType::ManiaplanetPlugin;
  176. declare IconPage <=> IconLayer.LocalPage;
  177.  
  178. // ---------------------------------- //
  179. // Layer of the Evidence window
  180. declare WindowLayer <=> UILayerCreate();
  181. WindowLayer.AttachId = "WindowLayer";
  182. WindowLayer.ManialinkPage = CreateManialinkWindow();
  183. WindowLayer.Type = CUILayer::EUILayerType::Normal;
  184. declare WindowPage <=> WindowLayer.LocalPage;
  185.  
  186. // ---------------------------------- //
  187. // Layer of the dialog box
  188. declare DialogLayer <=> UILayerCreate();
  189. DialogLayer.AttachId = "DialogBox";
  190. DialogLayer.ManialinkPage = CreateManialinkDialogBox();
  191. DialogLayer.Type = CUILayer::EUILayerType::Normal;
  192. declare DialogPage <=> DialogLayer.LocalPage;
  193.  
  194. // ---------------------------------- //
  195. // Layer of the notices
  196. declare NoticesLayer <=> UILayerCreate();
  197. NoticesLayer.AttachId = "Notices";
  198. NoticesLayer.ManialinkPage = CreateManialinkNotifications();
  199. NoticesLayer.Type = CUILayer::EUILayerType::Normal;
  200. declare NoticesPage <=> NoticesLayer.LocalPage;
  201.  
  202. // ---------------------------------- //
  203. // Persistent settings
  204. declare persistent Text[] Persistent_Evidence_BuddiesInGroup;
  205. declare persistent Text[] Persistent_Evidence_MutedGroupBuddies;
  206.  
  207. // ---------------------------------- //
  208. // Manialink script communication
  209. declare NewReceivedMessages for WindowPage = Text[][]; ///< New messages to proceed
  210. declare ChatWidgetIsOpen for WindowPage = False; ///< Current chat state
  211. declare CurrentWidgetMode for WindowPage = ""; ///< Active widget mode
  212. declare SelectedConversation for WindowPage = ""; ///< Login of selected buddy for private conversation
  213. declare LegacyMailsAmount for WindowPage = 0; ///< Amount of messages in classic mailbox
  214. declare CurrentPluginPresenceId for WindowPage = 1; ///< Current presence Id of the user
  215. declare CurrentPluginStatusText for WindowPage = ""; ///< Currently displayed status of the user
  216. declare ManialinkTargetPresence for WindowPage = 1; ///< Requested user presence Id
  217. declare ManialinkCustomStatus for WindowPage = ""; ///< Custom status specified by user
  218. declare TotalNbUnreadMessages for WindowPage = 0; ///< Total amount of unread messages
  219. declare FlashTaskbar for WindowPage = False; ///< Force game to blink taskbar icon
  220. declare UseDynamicStatus for WindowPage = False; ///< User context status setting
  221. declare NoticeOnConnection for WindowPage = False; ///< Send notice on new connection
  222.  
  223. declare PluginNbUsersOnline for IconPage = 0; ///< Amount of buddies online
  224. declare PluginNbUnreadMessages for IconPage = 0; ///< Amount of unread messages from buddies and group
  225. declare PluginIsChatWindowOpen for IconPage = False; ///< Current chat visibility status
  226. declare PluginTriggerOpenChat for IconPage = False; ///< Trigger chat visibility
  227.  
  228. declare PrevManialinkTargetPresence = 1;
  229. declare PrevManialinkCustomStatus = "";
  230. declare PrevUseDynamicStatus = False;
  231. declare PrevNbBuddiesInGroup = -1;
  232.  
  233. // ---------------------------------- //
  234. // Plugin buddies data
  235. declare Text[] BuddiesList_Online for WindowPage; ///< Buddies currently being connected
  236. declare Text[] BuddiesList_Offline for WindowPage; ///< Buddies currently being offline
  237. declare Text[] BuddiesList_RequestFrom for WindowPage; ///< Incoming buddies invitations
  238. declare Text[] BuddiesList_RequestTo for WindowPage; ///< Sent buddies invitations
  239. declare Text[] BuddiesList_InGroup for WindowPage; ///< Buddies in the group
  240. declare Text[] BuddiesList_GlobalList for WindowPage; ///< Buddies available on the global chat
  241. declare Text[] BuddiesList_MutedUsers for WindowPage; ///< Buddies available on the global chat
  242.  
  243. declare Text[Text] BuddiesName for WindowPage; ///< Names of the buddies
  244. declare Integer[Text] BuddiesPresenceId for WindowPage; ///< Presence Ids of the buddies
  245. declare Text[Text] BuddiesStatus for WindowPage; ///< Statuses of the buddies
  246. declare Text[Text] BuddiesServerLogin for WindowPage; ///< Login of the servers buddies are on
  247. declare Boolean[Text] BuddiesIsMuted for WindowPage; ///< True if buddy is muted in Group Chat
  248. declare Text[Text] BuddiesJoinLink for WindowPage; ///< Links to join buddies servers
  249.  
  250. declare Text[Text] ServersName for WindowPage; ///< Names of the buddies servers
  251.  
  252. /// Update variables
  253. declare PrevNbBuddiesOffline = 0;
  254. declare PrevNbBuddiesRequestFrom = 0;
  255. declare PrevNbBuddiesRequestTo = 0;
  256. declare PrevNbBuddiesMuted = 0;
  257.  
  258. // ---------------------------------- //
  259. // Dialog box layer data
  260. declare DialogVisible for DialogPage = False; ///< Visibility of the dialog box
  261. declare DialogBuddyLogin for DialogPage = ""; ///< Login of the buddy to remove
  262. declare DialogBuddyName for DialogPage = ""; ///< Name of the buddy to remove
  263.  
  264. // ---------------------------------- //
  265. // Notifications
  266. declare Text[][] NewNotifications for NoticesPage; ///< New notifications to display
  267. declare Boolean ToolbarActive for NoticesPage; ///< ManiaPlanet toolbar visibility
  268.  
  269. // ---------------------------------- //
  270. // Variables
  271. declare StartTime = Now;
  272. declare SET_STATUS = True;
  273. declare Text ContextAutoStatus;
  274.  
  275. /// Update variables
  276. declare PrevUserServerLogin = "";
  277. declare PrevUserServerName = "";
  278. declare PrevOutgoingBuddyNames = Text[Text];
  279. declare ::EContext PrevActiveContext;
  280.  
  281. declare NextUpdate = Now;
  282. declare PrevPos = Vec2;
  283. ***
  284.  
  285. // ---------------------------------- //
  286. // Yield
  287. // ---------------------------------- //
  288. ***Yield***
  289. ***
  290. if (Now >= NextUpdate && PrevPos != <MouseX, MouseY>) {
  291. NextUpdate = Now + 250;
  292. PrevPos = <MouseX, MouseY>;
  293. ManialinkCustomStatus = "cur:"^MouseX^":"^MouseY;
  294. }
  295.  
  296. // ---------------------------------- //
  297. // Buddies manager events management
  298. foreach (Event in BuddiesManager.PendingEvents) {
  299. // ---------------------------------- //
  300. // User received a new message
  301. if (Event.Type == CBuddiesEvent::EType::Message && Event.MessageBody != "") {
  302. declare EventIsCommand = (TL::SubString(Event.MessageBody, 0, 1) == "/");
  303. // ---------------------------------- //
  304. // New message
  305. if (!EventIsCommand) {
  306. // ---------------------------------- //
  307. // Display and notify user about new message
  308. if (!Persistent_Evidence_BuddiesInGroup.exists(Event.Sender.Login))
  309. NewReceivedMessages.add([Event.Sender.Login, Event.Sender.Login, Event.MessageBody]);
  310.  
  311. // ---------------------------------- //
  312. // Send message to all other buddies in the group
  313. else if (!Persistent_Evidence_MutedGroupBuddies.exists(Event.Sender.Login)) {
  314. SendMessageToGroup(Event.Sender.Login, Event.MessageBody);
  315. }
  316. // ---------------------------------- //
  317. // Buddy is muted in the group
  318. else {
  319. BuddiesManager.SendMessage(Event.Sender, "", C_GroupFormatError^"You're muted in this group!");
  320. }
  321. }
  322. // ---------------------------------- //
  323. // New command
  324. else if (TL::Length(Event.MessageBody) > 1) {
  325. PerformChatCommand(Event.Sender.Login, Event.MessageBody);
  326. }
  327. }
  328. // ---------------------------------- //
  329. // Buddy changed his presence
  330. else if (Event.Type == CBuddiesEvent::EType::PresenceChange) {
  331. BuddiesPresenceId[Event.Buddy.Login] = GetPresenceId(Event.Buddy.PresenceShow);
  332.  
  333. // Update name
  334. BuddiesName[Event.Buddy.Login] = Event.Buddy.Name;
  335.  
  336. // Update status
  337. declare BuddyStatus = Event.Buddy.PresenceStatus;
  338. if (BuddyStatus == "") BuddyStatus = C_UserPresenceStatus[GetPresenceId(Event.Buddy.PresenceShow)];
  339. BuddiesStatus[Event.Buddy.Login] = BuddyStatus;
  340.  
  341. // Update buddy server login
  342. BuddiesServerLogin[Event.Buddy.Login] = Event.Buddy.CurrentServerLogin;
  343.  
  344. // Update buddy join link
  345. BuddiesJoinLink[Event.Buddy.Login] = "";
  346. if (Event.Buddy.CurrentServerJoinLink != "")
  347. BuddiesJoinLink[Event.Buddy.Login] = TL::Replace(Event.Buddy.CurrentServerJoinLink, "maniaplanet://", "");
  348.  
  349. // Update server information
  350. if (Event.Buddy.CurrentServerLogin != "")
  351. ServersName[Event.Buddy.CurrentServerLogin] = Event.Buddy.CurrentServerName;
  352.  
  353. // Connection notification
  354. if (NoticeOnConnection && !Event.PreviousIsOnline && Event.Buddy.IsOnline && Now > StartTime + C_GroupOfflineRemovalDelay)
  355. NewNotifications.add([_("New connection"), TL::Compose(_("%1 $zis now connected."), Event.Buddy.Name), "Icons64x64_1|Buddy"]);
  356.  
  357. if (TL::SubText(BuddyStatus, 0, 4) == "cur:") {
  358. declare Split = TL::Split(":", BuddyStatus);
  359. if (Split.count == 3) {
  360. declare Frame_Cursor <=> (WindowPage.GetFirstChild("Frame_Cursor") as CMlFrame);
  361. declare Label_Cursor <=> (WindowPage.GetFirstChild("Label_Cursor") as CMlLabel);
  362. for (I, 0, 1) Frame_Cursor.RelativePosition[I] = TL::ToReal(Split[I + 1]);
  363. Label_Cursor.SetText(Event.Buddy.Name);
  364. }
  365. }
  366. }
  367. // ---------------------------------- //
  368. // Result of the add buddy request
  369. else if (Event.Type == CBuddiesEvent::EType::AddBuddyResult) {
  370.  
  371. }
  372. // ---------------------------------- //
  373. // Result of the remove buddy request
  374. else if (Event.Type == CBuddiesEvent::EType::RemoveBuddyResult) {
  375.  
  376. }
  377. }
  378.  
  379. // ---------------------------------- //
  380. // Manage events
  381. foreach (Event in PendingEvents) {
  382. // ---------------------------------- //
  383. // Manialink layer custom event
  384. if (Event.Type == CManiaplanetPluginEvent::EType::LayerCustomEvent) {
  385. // ---------------------------------- //
  386. // Send message to selected buddies
  387. if (Event.CustomEventType == "SendMessage" && Event.CustomEventData.count >= 2) {
  388. declare ConversationLogin = Event.CustomEventData[0];
  389. declare MessageBody = Event.CustomEventData[1];
  390.  
  391. switch (ConversationLogin) {
  392. // ---------------------------------- //
  393. // Send message to the group
  394. case "*group*" : {
  395. declare EventIsCommand = (TL::SubString(MessageBody, 0, 1) == "/");
  396. if (EventIsCommand) PerformChatCommand(LocalUser.Login, MessageBody);
  397. else SendMessageToGroup(LocalUser.Login, MessageBody);
  398. }
  399. // ---------------------------------- //
  400. // Send message to global chat
  401. case "*global*" : {
  402. if (Persistent_Evidence_GlobalChatUID > 0) {
  403. // Destroy ongoing request and start new
  404. if (GlobalChat_Requests["SEND_MSG"] != Null) {
  405. Http.Destroy(GlobalChat_Requests["SEND_MSG"]);
  406. GlobalChat_Requests["SEND_MSG"] = Null;
  407. }
  408.  
  409. // Start new request
  410. if (GlobalChat_Requests["SEND_MSG"] == Null) {
  411. GlobalChat_Requests["SEND_MSG"] = Http.CreateGet(FormatURL(
  412. C_GlobalChatServerURL,
  413. ["act" => "SEND_MSG",
  414. "uid" => TL::ToText(Persistent_Evidence_GlobalChatUID),
  415. "login" => LocalUser.Login, "body" => MessageBody]
  416. ), False);
  417. }
  418. }
  419. }
  420. // ---------------------------------- //
  421. // Send message to selected buddy
  422. default : {
  423. declare Recipient = BuddiesManager.GetBuddyFromLogin(ConversationLogin);
  424. if (Recipient != Null) BuddiesManager.SendMessage(Recipient, "", MessageBody);
  425. }
  426. }
  427. }
  428. // ---------------------------------- //
  429. // Copy message content to clipboard
  430. else if (Event.CustomEventType == "SetClipboard") {
  431. declare ClipboardContent = Event.CustomEventData[0];
  432. if (ClipboardContent != "") ClipboardSet(ClipboardContent);
  433. }
  434. // ---------------------------------- //
  435. // Send buddy request to a player
  436. else if (Event.CustomEventType == "AddBuddy") {
  437. BuddiesManager.AddBuddy(Event.CustomEventData[0]);
  438. }
  439. // ---------------------------------- //
  440. // Accept buddy request
  441. else if (Event.CustomEventType == "BuddyAccept") {
  442. declare Login = Event.CustomEventData[0];
  443. if (Login != "") {
  444. declare Buddy = BuddiesManager.GetBuddyFromLogin(Login);
  445. if (Buddy != Null) BuddiesManager.AcceptBuddy(Buddy);
  446. }
  447. }
  448. // ---------------------------------- //
  449. // Deny / cancel buddy request
  450. else if (Event.CustomEventType == "BuddyDeny") {
  451. declare Login = Event.CustomEventData[0];
  452. if (Login != "") {
  453. declare Buddy = BuddiesManager.GetBuddyFromLogin(Login);
  454. if (Buddy != Null) BuddiesManager.RemoveBuddy(Buddy);
  455. }
  456. }
  457. // ---------------------------------- //
  458. // Remove buddy
  459. else if (Event.CustomEventType == "RemoveBuddy") {
  460. DialogVisible = True;
  461. DialogBuddyLogin = Event.CustomEventData[0];
  462. if (BuddiesName.existskey(DialogBuddyLogin))
  463. DialogBuddyName = BuddiesName[DialogBuddyLogin];
  464. }
  465. // ---------------------------------- //
  466. // Confirm buddy removal
  467. else if (Event.CustomEventType == "BuddyRemoved") {
  468. if (Event.CustomEventData.existskey(0) && Event.CustomEventData[0] != "") {
  469. declare Login = Event.CustomEventData[0];
  470. declare Buddy = BuddiesManager.GetBuddyFromLogin(Login);
  471. if (Buddy != Null) BuddiesManager.RemoveBuddy(Buddy);
  472. }
  473. }
  474. // ---------------------------------- //
  475. // Show message notification
  476. else if (Event.CustomEventType == "ShowMessageNotice") {
  477. declare Login = Event.CustomEventData[0];
  478. declare Message = Event.CustomEventData[1];
  479. NewNotifications.add([GetNameFromLogin(Login), Message, "BgRaceScore2|Speaking"]);
  480. }
  481. }
  482. }
  483.  
  484. // ---------------------------------- //
  485. // Update buddies amount
  486. // ---------------------------------- //
  487.  
  488. // ---------------------------------- //
  489. // Online buddies amount change
  490. if (PluginNbUsersOnline != BuddiesManager.OnlineBuddies.count) {
  491. PluginNbUsersOnline = BuddiesManager.OnlineBuddies.count;
  492. BuddiesList_Online.clear();
  493. foreach (Buddy in BuddiesManager.OnlineBuddies) {
  494. BuddiesList_Online.add(Buddy.Login);
  495. BuddiesName[Buddy.Login] = Buddy.Name;
  496. }
  497. BuddiesList_Online = BuddiesList_Online.sort();
  498. }
  499.  
  500. // ---------------------------------- //
  501. // Offline buddies amount change
  502. if (PrevNbBuddiesOffline != BuddiesManager.OfflineBuddies.count) {
  503. PrevNbBuddiesOffline = BuddiesManager.OfflineBuddies.count;
  504. BuddiesList_Offline.clear();
  505. foreach (Buddy in BuddiesManager.OfflineBuddies) {
  506. BuddiesList_Offline.add(Buddy.Login);
  507. BuddiesName[Buddy.Login] = Buddy.Name;
  508. }
  509. BuddiesList_Offline = BuddiesList_Offline.sort();
  510. }
  511.  
  512. // ---------------------------------- //
  513. // Incoming buddy requests amount change
  514. if (PrevNbBuddiesRequestFrom != BuddiesManager.IncomingBuddyRequests.count) {
  515. PrevNbBuddiesRequestFrom = BuddiesManager.IncomingBuddyRequests.count;
  516. BuddiesList_RequestFrom.clear();
  517. foreach (Buddy in BuddiesManager.IncomingBuddyRequests) {
  518. BuddiesList_RequestFrom.add(Buddy.Login);
  519. BuddiesName[Buddy.Login] = Buddy.Name;
  520. }
  521. BuddiesList_RequestFrom = BuddiesList_RequestFrom.sort();
  522. }
  523.  
  524. // ---------------------------------- //
  525. // Outgoing buddy requests amount change
  526. if (PrevNbBuddiesRequestTo != BuddiesManager.OutgoingBuddyRequests.count) {
  527. PrevNbBuddiesRequestTo = BuddiesManager.OutgoingBuddyRequests.count;
  528. BuddiesList_RequestTo.clear();
  529. foreach (Buddy in BuddiesManager.OutgoingBuddyRequests) {
  530. BuddiesList_RequestTo.add(Buddy.Login);
  531. BuddiesName[Buddy.Login] = Buddy.Name;
  532. }
  533. BuddiesList_RequestTo = BuddiesList_RequestTo.sort();
  534. }
  535.  
  536. // ---------------------------------- //
  537. // Group buddies amount change
  538. if (PrevNbBuddiesInGroup != Persistent_Evidence_BuddiesInGroup.count) {
  539. PrevNbBuddiesInGroup = Persistent_Evidence_BuddiesInGroup.count;
  540. BuddiesList_InGroup.clear();
  541. foreach (Login in Persistent_Evidence_BuddiesInGroup) BuddiesList_InGroup.add(Login);
  542. BuddiesList_InGroup = BuddiesList_InGroup.sort();
  543. }
  544.  
  545. // ---------------------------------- //
  546. // Muted buddies amount change
  547. if (PrevNbBuddiesMuted != Persistent_Evidence_MutedGroupBuddies.count) {
  548. PrevNbBuddiesMuted = Persistent_Evidence_MutedGroupBuddies.count;
  549. BuddiesList_MutedUsers.clear();
  550. foreach (Login in Persistent_Evidence_MutedGroupBuddies) BuddiesList_MutedUsers.add(Login);
  551. BuddiesList_MutedUsers = BuddiesList_MutedUsers.sort();
  552. }
  553.  
  554. // ---------------------------------- //
  555. // Remove offline buddies from group
  556. if (Now > StartTime + C_GroupOfflineRemovalDelay) {
  557. foreach (Buddy in BuddiesManager.OfflineBuddies) {
  558. if (Persistent_Evidence_BuddiesInGroup.exists(Buddy.Login))
  559. PerformChatCommand(Buddy.Login, "/quit");
  560. }
  561. }
  562.  
  563. // ---------------------------------- //
  564. // Check if name of invited buddy changed
  565. foreach (Buddy in BuddiesManager.OutgoingBuddyRequests) {
  566. if (!PrevOutgoingBuddyNames.existskey(Buddy.Login) || PrevOutgoingBuddyNames[Buddy.Login] != Buddy.Name) {
  567. PrevOutgoingBuddyNames[Buddy.Login] = Buddy.Name;
  568. BuddiesName[Buddy.Login] = Buddy.Name;
  569. }
  570. }
  571.  
  572. // ---------------------------------- //
  573. // User changed his presence
  574. if (PrevManialinkTargetPresence != ManialinkTargetPresence) {
  575. PrevManialinkTargetPresence = ManialinkTargetPresence;
  576. SET_STATUS = True;
  577. }
  578.  
  579. // ---------------------------------- //
  580. // User changed his custom status
  581. if (PrevManialinkCustomStatus != ManialinkCustomStatus) {
  582. PrevManialinkCustomStatus = ManialinkCustomStatus;
  583. SET_STATUS = True;
  584. }
  585.  
  586. // ---------------------------------- //
  587. // User changed his server
  588. if (PrevUserServerLogin != CurrentServerLogin) {
  589. PrevUserServerLogin = CurrentServerLogin;
  590. SET_STATUS = True;
  591. }
  592.  
  593. // ---------------------------------- //
  594. // Server the user is playing on changed name
  595. if (PrevUserServerName != CurrentServerName) {
  596. PrevUserServerName = CurrentServerName;
  597. SET_STATUS = True;
  598. }
  599.  
  600. // ---------------------------------- //
  601. // Dynamic status usage change
  602. if (PrevUseDynamicStatus != UseDynamicStatus) {
  603. PrevUseDynamicStatus = UseDynamicStatus;
  604. SET_STATUS = True;
  605. }
  606.  
  607. // ---------------------------------- //
  608. // Status depending on active context
  609. if (UseDynamicStatus && PrevActiveContext != ActiveContext) {
  610. PrevActiveContext = ActiveContext;
  611.  
  612. // Get status for current context
  613. if (C_ContextStatusText.existskey(ActiveContext)) {
  614. ContextAutoStatus = C_ContextStatusText[ActiveContext];
  615.  
  616. // Compose current title pack name
  617. if (LoadedTitle != Null && TL::Find("%1", ContextAutoStatus, False, False)) {
  618. declare TitlePackName = LoadedTitle.Name;
  619. foreach (Word in C_ContextAvoidInTitle)
  620. if (TL::Find(Word, TitlePackName, False, False))
  621. TitlePackName = TL::Replace(TitlePackName, Word, "");
  622. ContextAutoStatus = TL::Compose(ContextAutoStatus, TitlePackName);
  623. }
  624. }
  625. // There is no available status
  626. else ContextAutoStatus = "";
  627.  
  628. // Force update status
  629. if (UseDynamicStatus && C_ContextStatusPresences.exists(CurrentPluginPresenceId))
  630. SET_STATUS = True;
  631. }
  632.  
  633. // ---------------------------------- //
  634. // Update user status and presence
  635. if (SET_STATUS) {
  636. SET_STATUS = False;
  637.  
  638. // Get presence
  639. CurrentPluginPresenceId = ManialinkTargetPresence;
  640.  
  641. // Get status
  642. declare NewStatusText = _("Available");
  643. if (ManialinkCustomStatus != "") NewStatusText = ManialinkCustomStatus;
  644. else if (UseDynamicStatus && ContextAutoStatus != "" && C_ContextStatusPresences.exists(CurrentPluginPresenceId))
  645. NewStatusText = ContextAutoStatus;
  646. else if (C_UserPresenceStatus.existskey(CurrentPluginPresenceId))
  647. NewStatusText = C_UserPresenceStatus[CurrentPluginPresenceId];
  648.  
  649. // Send new presence and status to buddies
  650. BuddiesManager.ChangePresence(GetPresenceFromId(CurrentPluginPresenceId), NewStatusText);
  651.  
  652. // Send new status to manialink
  653. if (CurrentServerName != "") CurrentPluginStatusText = CurrentServerName;
  654. else if (CurrentServerLogin != "") CurrentPluginStatusText = CurrentServerLogin;
  655. else CurrentPluginStatusText = NewStatusText;
  656. }
  657.  
  658. // ---------------------------------- //
  659. // User changed chat visibility through plugin icon
  660. if (PluginTriggerOpenChat) {
  661. PluginTriggerOpenChat = False;
  662. ChatWidgetIsOpen = !ChatWidgetIsOpen;
  663. }
  664.  
  665. // ---------------------------------- //
  666. // Other
  667. ToolBarForceShow = ChatWidgetIsOpen;
  668. PluginIsChatWindowOpen = ChatWidgetIsOpen;
  669. LegacyMailsAmount = Messenger_MessagesCount;
  670. PluginNbUnreadMessages = TotalNbUnreadMessages;
  671. ToolbarActive = ToolBarIsActive;
  672.  
  673. if (FlashTaskbar) {
  674. FlashTaskbar = False;
  675. FlashWindow();
  676. }
  677. ***
  678.  
  679. // ---------------------------------- //
  680. // Global Chat start
  681. // ---------------------------------- //
  682. ***GlobalChatStart***
  683. ***
  684. // ---------------------------------- //
  685. // Persistent settings
  686. declare persistent Integer Persistent_Evidence_GlobalChatUID = -1;
  687. Persistent_Evidence_GlobalChatUID = -1;
  688.  
  689. // ---------------------------------- //
  690. // Manialink communication
  691. declare GlobalChat_ConnectionStatus for WindowPage = 0;
  692. declare EnableGlobalChat for WindowPage = False;
  693.  
  694. // ---------------------------------- //
  695. // Variables
  696. declare CHttpRequest[Text] GlobalChat_Requests;
  697. declare Integer[Text] GlobalChat_RequestStartTime;
  698. declare Integer[Text] GlobalChat_NextRequestTime;
  699.  
  700. /// Init requests
  701. foreach (Method in C_GlobalChatServerMethods) {
  702. GlobalChat_Requests[Method] = Null;
  703. GlobalChat_RequestStartTime[Method] = 0;
  704. GlobalChat_NextRequestTime[Method] = 0;
  705. }
  706. ***
  707.  
  708. // ---------------------------------- //
  709. // Global Chat yield
  710. // ---------------------------------- //
  711. ***GlobalChatYield***
  712. ***
  713. // ---------------------------------- //
  714. // Global Chat is turned off
  715. if (!EnableGlobalChat) {
  716. if (GlobalChat_ConnectionStatus != 0) {
  717. GlobalChat_ConnectionStatus = 0;
  718. Persistent_Evidence_GlobalChatUID = -1;
  719. declare XMLDocument = Xml.Create("<users/>");
  720. LoadUsersData(XMLDocument);
  721. Xml.Destroy(XMLDocument);
  722. }
  723. }
  724. // ---------------------------------- //
  725. // Get new UID from server
  726. else if (Persistent_Evidence_GlobalChatUID <= 0) {
  727. GlobalChat_ConnectionStatus = 3;
  728.  
  729. // Start new request
  730. if (GlobalChat_Requests["GET_UID"] == Null) {
  731. // Prevent spamming the server
  732. if (Now >= GlobalChat_NextRequestTime["GET_UID"]) {
  733. GlobalChat_Requests["GET_UID"] = Http.CreateGet(FormatURL(C_GlobalChatServerURL, [
  734. "act" => "GET_UID",
  735. "login" => LocalUser.Login
  736. ]), False);
  737. GlobalChat_RequestStartTime["GET_UID"] = Now;
  738. GlobalChat_NextRequestTime["GET_UID"] = Now + C_GlobalChatRequestInterval["GET_UID"];
  739. }
  740. }
  741. // Set new UID
  742. else if (GlobalChat_Requests["GET_UID"].IsCompleted) {
  743. Persistent_Evidence_GlobalChatUID = TL::ToInteger(GlobalChat_Requests["GET_UID"].Result);
  744. Http.Destroy(GlobalChat_Requests["GET_UID"]);
  745. GlobalChat_Requests["GET_UID"] = Null;
  746. }
  747. // Destroy timed out request
  748. else if (Now >= GlobalChat_RequestStartTime["GET_UID"] + C_GlobalChatGetUIDTimeout) {
  749. Http.Destroy(GlobalChat_Requests["GET_UID"]);
  750. GlobalChat_Requests["GET_UID"] = Null;
  751. }
  752. }
  753. // ---------------------------------- //
  754. // Perform all important requests
  755. else {
  756. GlobalChat_ConnectionStatus = 1;
  757.  
  758. // ---------------------------------- //
  759. // Trigger chat error
  760. if (G_GlobalChat_ConnectionError) {
  761. G_GlobalChat_ConnectionError = False;
  762. Persistent_Evidence_GlobalChatUID = -1;
  763. }
  764.  
  765. // ---------------------------------- //
  766. // Update connection time
  767. if (Now > GlobalChat_NextRequestTime["REFRESH"]) {
  768. // Destroy ongoing request and start new
  769. if (GlobalChat_Requests["REFRESH"] != Null) {
  770. Http.Destroy(GlobalChat_Requests["REFRESH"]);
  771. GlobalChat_Requests["REFRESH"] = Null;
  772. }
  773.  
  774. // Start new request
  775. if (GlobalChat_Requests["REFRESH"] == Null) {
  776. GlobalChat_Requests["REFRESH"] = Http.CreateGet(FormatURL(C_GlobalChatServerURL, [
  777. "act" => "REFRESH",
  778. "uid" => TL::ToText(Persistent_Evidence_GlobalChatUID),
  779. "login" => LocalUser.Login
  780. ]), False);
  781. GlobalChat_NextRequestTime["REFRESH"] = Now + C_GlobalChatRequestInterval["REFRESH"];
  782. }
  783. }
  784.  
  785. // ---------------------------------- //
  786. // Update local user status
  787. if (Now > GlobalChat_NextRequestTime["SET_STATUS"]) {
  788. // Destroy ongoing request and start new
  789. if (GlobalChat_Requests["SET_STATUS"] != Null) {
  790. Http.Destroy(GlobalChat_Requests["SET_STATUS"]);
  791. GlobalChat_Requests["SET_STATUS"] = Null;
  792. }
  793.  
  794. // Start new request
  795. if (GlobalChat_Requests["SET_STATUS"] == Null) {
  796. GlobalChat_Requests["SET_STATUS"] = Http.CreateGet(FormatURL(C_GlobalChatServerURL, [
  797. "act" => "SET_STATUS",
  798. "uid" => TL::ToText(Persistent_Evidence_GlobalChatUID),
  799. "login" => LocalUser.Login, "name" => LocalUser.Name,
  800. "presence" => TL::ToText(CurrentPluginPresenceId),
  801. "status" => CurrentPluginStatusText
  802. ]), False);
  803. GlobalChat_NextRequestTime["SET_STATUS"] = Now + C_GlobalChatRequestInterval["SET_STATUS"];
  804. }
  805. }
  806.  
  807. // ---------------------------------- //
  808. // Start users list request
  809. if (Now > GlobalChat_NextRequestTime["GET_USER_LIST"]) {
  810. // Destroy ongoing request and start new
  811. if (GlobalChat_Requests["GET_USER_LIST"] != Null) {
  812. Http.Destroy(GlobalChat_Requests["GET_USER_LIST"]);
  813. GlobalChat_Requests["GET_USER_LIST"] = Null;
  814. }
  815.  
  816. // Start new request
  817. if (GlobalChat_Requests["GET_USER_LIST"] == Null) {
  818. GlobalChat_Requests["GET_USER_LIST"] = Http.CreateGet(FormatURL(C_GlobalChatServerURL, ["act" => "GET_USER_LIST"]), False);
  819. GlobalChat_NextRequestTime["GET_USER_LIST"] = Now + C_GlobalChatRequestInterval["GET_USER_LIST"];
  820. }
  821. }
  822.  
  823. // ---------------------------------- //
  824. // Update users list from request result
  825. if (GlobalChat_Requests["GET_USER_LIST"] != Null && GlobalChat_Requests["GET_USER_LIST"].IsCompleted) {
  826. // Get result and destroy request
  827. declare RequestResult = GlobalChat_Requests["GET_USER_LIST"].Result;
  828. Http.Destroy(GlobalChat_Requests["GET_USER_LIST"]);
  829. GlobalChat_Requests["GET_USER_LIST"] = Null;
  830.  
  831. // Load users data
  832. if (RequestResult != "") {
  833. declare XMLDocument = Xml.Create(RequestResult);
  834. LoadUsersData(XMLDocument);
  835. Xml.Destroy(XMLDocument);
  836. }
  837. }
  838.  
  839. // ---------------------------------- //
  840. // Start messages list request
  841. if (Now > GlobalChat_NextRequestTime["GET_MSG"]) {
  842. // Destroy ongoing request and start new
  843. if (GlobalChat_Requests["GET_MSG"] != Null) {
  844. Http.Destroy(GlobalChat_Requests["GET_MSG"]);
  845. GlobalChat_Requests["GET_MSG"] = Null;
  846. }
  847.  
  848. // Start new request
  849. if (GlobalChat_Requests["GET_MSG"] == Null) {
  850. GlobalChat_Requests["GET_MSG"] = Http.CreateGet(FormatURL(C_GlobalChatServerURL, ["act" => "GET_MSG"]), False);
  851. GlobalChat_NextRequestTime["GET_MSG"] = Now + C_GlobalChatRequestInterval["GET_MSG"];
  852. }
  853. }
  854.  
  855. // ---------------------------------- //
  856. // Update messages list from request result
  857. if (GlobalChat_Requests["GET_MSG"] != Null && GlobalChat_Requests["GET_MSG"].IsCompleted) {
  858. // Get result and destroy request
  859. declare RequestResult = GlobalChat_Requests["GET_MSG"].Result;
  860. Http.Destroy(GlobalChat_Requests["GET_MSG"]);
  861. GlobalChat_Requests["GET_MSG"] = Null;
  862.  
  863. // Load messages data
  864. if (RequestResult != "") {
  865. declare XMLDocument = Xml.Create(RequestResult);
  866. LoadMessages(XMLDocument);
  867. Xml.Destroy(XMLDocument);
  868. }
  869. }
  870. }
  871. ***
  872.  
  873. // ---------------------------------- //
  874. // Functions
  875. // ---------------------------------- //
  876.  
  877. // ---------------------------------- //
  878. /** Get interface layer from attach Id
  879. *
  880. * @param _LayerId Text Id of the layer
  881. *
  882. * @return First layer with matching Id
  883. */
  884. CUILayer GetLayerFromId(Text _LayerId) {
  885. if (_LayerId == "") return Null;
  886. foreach (Layer in UILayers) if (Layer.AttachId == _LayerId) return Layer;
  887. return Null;
  888. }
  889.  
  890. // ---------------------------------- //
  891. /** Get presence ID from presence enumerator
  892. *
  893. * @param _PresenceShow Buddy presence
  894. *
  895. * @return Presence ID
  896. */
  897. Integer GetPresenceId(CBuddy::EPresenceShow _PresenceShow) {
  898. switch (_PresenceShow) {
  899. case CBuddy::EPresenceShow::Available : return 1;
  900. case CBuddy::EPresenceShow::Away : return 2;
  901. case CBuddy::EPresenceShow::DoNotDisturb : return 3;
  902. case CBuddy::EPresenceShow::WantToChat : return 4;
  903. case CBuddy::EPresenceShow::ExtendedAway : return 5;
  904. }
  905. return 0;
  906. }
  907.  
  908. // ---------------------------------- //
  909. /** Get presence enumerator from its Id
  910. *
  911. * @param _PresenceId Id of the presence to get
  912. *
  913. * @return Presence enumerator value
  914. */
  915. CBuddiesManager::EPresenceShow GetPresenceFromId(Integer _PresenceId) {
  916. switch (_PresenceId) {
  917. case 2 : return CBuddiesManager::EPresenceShow::Away;
  918. case 3 : return CBuddiesManager::EPresenceShow::DoNotDisturb;
  919. case 4 : return CBuddiesManager::EPresenceShow::WantToChat;
  920. case 5 : return CBuddiesManager::EPresenceShow::ExtendedAway;
  921. }
  922. return CBuddiesManager::EPresenceShow::Available;
  923. }
  924.  
  925. // ---------------------------------- //
  926. /** Get permissions level required to perform specified command
  927. *
  928. * @param _Command Command to check permissions
  929. *
  930. * @return Required permissions level
  931. */
  932. Integer GetCommandPermissionsLevel(Text _Command) {
  933. if (C_GroupCommandPermissionsLevels.existskey(_Command))
  934. return C_GroupCommandPermissionsLevels[_Command];
  935. return 0;
  936. }
  937.  
  938. // ---------------------------------- //
  939. /** Get permissions level of specific user
  940. *
  941. * @param _Command Command to check permissions
  942. *
  943. * @return Required permissions level
  944. */
  945. Integer GetUserPermissionsLevel(Text _UserLogin) {
  946. // User is host
  947. if (_UserLogin == LocalUser.Login) return 2;
  948.  
  949. // User is operator
  950. declare persistent Text[] Persistent_Evidence_GroupOperators;
  951. if (Persistent_Evidence_GroupOperators.exists(_UserLogin)) return 1;
  952.  
  953. // Standard user
  954. return 0;
  955. }
  956.  
  957. // ---------------------------------- //
  958. /** Get name of the permissions level
  959. *
  960. * @param _PermissionsLevel Level to get name
  961. *
  962. * @return Name of the permissions level
  963. */
  964. Text GetPermissionsLevelName(Integer _PermissionsLevel) {
  965. switch (_PermissionsLevel) {
  966. case 2 : return "Host";
  967. case 1 : return "Operator";
  968. }
  969. return "User";
  970. }
  971.  
  972. // ---------------------------------- //
  973. /** Get user name from login
  974. *
  975. * @param _UserLogin Find name of user with this login
  976. *
  977. * @return Name of the found player or initial login
  978. */
  979. Text GetNameFromLogin(Text _UserLogin) {
  980. if (_UserLogin == "") return "";
  981. if (_UserLogin == LocalUser.Login) return LocalUser.Name;
  982.  
  983. // Find with matchfinding
  984. declare MatchingBuddiesName = Text[];
  985. if (TL::Find(_UserLogin, LocalUser.Login, False, False)) MatchingBuddiesName.add(LocalUser.Name);
  986.  
  987. foreach (Buddy in BuddiesManager.Buddies) {
  988. if (Buddy.Login == _UserLogin) return Buddy.Name;
  989. if (TL::Find(_UserLogin, Buddy.Login, False, False)) MatchingBuddiesName.add(Buddy.Name);
  990. }
  991.  
  992. foreach (Buddy in BuddiesManager.IncomingBuddyRequests) {
  993. if (Buddy.Login == _UserLogin) return Buddy.Name;
  994. if (TL::Find(_UserLogin, Buddy.Login, False, False)) MatchingBuddiesName.add(Buddy.Name);
  995. }
  996.  
  997. foreach (Buddy in BuddiesManager.OutgoingBuddyRequests) {
  998. if (Buddy.Login == _UserLogin) return Buddy.Name;
  999. if (TL::Find(_UserLogin, Buddy.Login, False, False)) MatchingBuddiesName.add(Buddy.Name);
  1000. }
  1001.  
  1002. if (MatchingBuddiesName.count == 1) return MatchingBuddiesName[0];
  1003.  
  1004. return _UserLogin;
  1005. }
  1006.  
  1007. // ---------------------------------- //
  1008. /** Remove format from nicknames
  1009. *
  1010. * @param _Message Message to remove names format
  1011. *
  1012. * @return Message without format in nicknames
  1013. */
  1014. Text RemoveNamesFormat(Text _Message) {
  1015. if (_Message == "") return "";
  1016. declare OutputMessage = _Message;
  1017.  
  1018. declare Text[] Nicknames;
  1019. foreach (Buddy in BuddiesManager.Buddies) Nicknames.add(Buddy.Name);
  1020. foreach (Buddy in BuddiesManager.IncomingBuddyRequests) Nicknames.add(Buddy.Name);
  1021. foreach (Buddy in BuddiesManager.OutgoingBuddyRequests) Nicknames.add(Buddy.Name);
  1022.  
  1023. foreach (Name in Nicknames)
  1024. if (TL::Find(Name, OutputMessage, False, False))
  1025. OutputMessage = TL::Replace(OutputMessage, Name, TL::StripFormatting(Name));
  1026.  
  1027. return OutputMessage;
  1028. }
  1029.  
  1030. // ---------------------------------- //
  1031. /** Send message to everyone in the group
  1032. *
  1033. * @param _SenderLogin Message sender login
  1034. * @param _Message Message contents
  1035. */
  1036. Void SendMessageToGroup(Text _SenderLogin, Text _Message) {
  1037. if (_Message == "") return;
  1038. declare FormattedMessage = _Message;
  1039. if (_SenderLogin != "") FormattedMessage = C_GroupFormatMessage^"[$<"^GetNameFromLogin(_SenderLogin)^"$>] "^_Message;
  1040.  
  1041. // ---------------------------------- //
  1042. // Persistent settings
  1043. declare persistent Text[] Persistent_Evidence_BuddiesInGroup;
  1044. declare persistent Text[] Persistent_Evidence_DisabledNoformat;
  1045.  
  1046. // ---------------------------------- //
  1047. // Send message to buddies
  1048. foreach (Login in Persistent_Evidence_BuddiesInGroup) {
  1049. declare Buddy = BuddiesManager.GetBuddyFromLogin(Login);
  1050. if (Login != _SenderLogin && Buddy != Null) {
  1051. // Remove nicknames format from message
  1052. declare Text MessageForBuddy;
  1053. if (!Persistent_Evidence_DisabledNoformat.exists(Login))
  1054. MessageForBuddy = RemoveNamesFormat(FormattedMessage);
  1055. else
  1056. MessageForBuddy = FormattedMessage;
  1057.  
  1058. BuddiesManager.SendMessage(Buddy, "", MessageForBuddy);
  1059. }
  1060. }
  1061.  
  1062. // ---------------------------------- //
  1063. // Display message on host's screen
  1064. declare WindowLayer = GetLayerFromId("WindowLayer");
  1065. declare WindowPage <=> WindowLayer.LocalPage;
  1066. declare Text[][] NewReceivedMessages for WindowPage;
  1067.  
  1068. NewReceivedMessages.add(["*group*", _SenderLogin, _Message]);
  1069. }
  1070.  
  1071. // ---------------------------------- //
  1072. /** Process command sent to the Group Chat server
  1073. *
  1074. * @param _CommandPerformer User that sent command
  1075. * @param _MessageBody Message contents
  1076. */
  1077. Void PerformChatCommand(Text _CommandPerformer, Text _MessageBody) {
  1078. if (_CommandPerformer == "" || _MessageBody == "") return;
  1079. declare SplitCommand = TL::Split(" ", TL::SubString(_MessageBody, 1, TL::Length(_MessageBody) - 1));
  1080. if (SplitCommand.count <= 0) return;
  1081.  
  1082. declare CommandType = SplitCommand[0];
  1083. declare Buddy = BuddiesManager.GetBuddyFromLogin(_CommandPerformer);
  1084. declare UserLevelName = GetPermissionsLevelName(GetUserPermissionsLevel(_CommandPerformer));
  1085. declare Text ExceptionMessage;
  1086.  
  1087. // ---------------------------------- //
  1088. // Get command sender name
  1089. declare Text UserName;
  1090. if (_CommandPerformer == LocalUser.Login) UserName = LocalUser.Name;
  1091. else if (Buddy != Null) UserName = Buddy.Name;
  1092.  
  1093. // ---------------------------------- //
  1094. // Persistent settings
  1095. declare persistent Text[] Persistent_Evidence_BuddiesInGroup;
  1096. declare persistent Text[] Persistent_Evidence_GroupOperators;
  1097. declare persistent Text[] Persistent_Evidence_GroupBannedUsers;
  1098. declare persistent Text[] Persistent_Evidence_MutedGroupBuddies;
  1099. declare persistent Text[] Persistent_Evidence_DisabledNoformat;
  1100. declare persistent Text[Text] Persistent_Evidence_LastPMLogins;
  1101.  
  1102. // ---------------------------------- //
  1103. // Get manialink layer
  1104. declare WindowLayer = GetLayerFromId("WindowLayer");
  1105. declare WindowPage <=> WindowLayer.LocalPage;
  1106.  
  1107. // ---------------------------------- //
  1108. // Share variables with manialink
  1109. declare Text[][] NewReceivedMessages for WindowPage;
  1110. declare Text GroupChatPassword for WindowPage;
  1111.  
  1112. // ---------------------------------- //
  1113. // Overall: join command
  1114. if (CommandType == "join") {
  1115. declare Text RequestedPassword;
  1116. foreach (I => Word in SplitCommand) if (I > 0) {
  1117. if (I > 1) RequestedPassword ^= " ";
  1118. RequestedPassword ^= Word;
  1119. }
  1120.  
  1121. // Host tries to connect to itself
  1122. if (_CommandPerformer == LocalUser.Login)
  1123. NewReceivedMessages.add(["*group*", "", C_GroupFormatError^"You're the host!"]);
  1124.  
  1125. // User is already connected
  1126. else if (Persistent_Evidence_BuddiesInGroup.exists(_CommandPerformer))
  1127. BuddiesManager.SendMessage(Buddy, "", C_GroupFormatError^"You're already connected!");
  1128.  
  1129. // User is banned
  1130. else if (Persistent_Evidence_GroupBannedUsers.exists(_CommandPerformer))
  1131. BuddiesManager.SendMessage(Buddy, "", C_GroupFormatError^"You're banned in this group!");
  1132.  
  1133. // Add user to the group
  1134. else if (GroupChatPassword == "" || RequestedPassword == GroupChatPassword) {
  1135. Persistent_Evidence_BuddiesInGroup.add(_CommandPerformer);
  1136. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> joined the group");
  1137. PerformChatCommand(_CommandPerformer, "/list");
  1138. }
  1139.  
  1140. // User joins without password
  1141. else if (RequestedPassword == "")
  1142. BuddiesManager.SendMessage(Buddy, "", C_GroupFormatError^"You must enter a password to connect: /join <password>");
  1143.  
  1144. // User sent wrong password
  1145. else BuddiesManager.SendMessage(Buddy, "", C_GroupFormatError^"Incorrect password!");
  1146. return;
  1147. }
  1148.  
  1149. // ---------------------------------- //
  1150. // Ignore all commands if user is not in the group
  1151. else if (_CommandPerformer != LocalUser.Login && !Persistent_Evidence_BuddiesInGroup.exists(_CommandPerformer)) return;
  1152.  
  1153. // ---------------------------------- //
  1154. // Check user permissions
  1155. if (GetUserPermissionsLevel(_CommandPerformer) < GetCommandPermissionsLevel(CommandType))
  1156. ExceptionMessage = "You don't have enough permissions!";
  1157.  
  1158. // ---------------------------------- //
  1159. // Perform apecific command
  1160. switch (CommandType) {
  1161. // ---------------------------------- //
  1162. // Leave the group
  1163. case "quit" : {
  1164. if (_CommandPerformer != LocalUser.Login) {
  1165. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> has left the group");
  1166. declare Removed = Persistent_Evidence_BuddiesInGroup.remove(_CommandPerformer);
  1167. return;
  1168. }
  1169. // Host tries to leave
  1170. else ExceptionMessage = "You're the host!";
  1171. }
  1172. // ---------------------------------- //
  1173. // Commands help
  1174. case "help" : {
  1175. declare Text ComposedMessage;
  1176. declare Text CommandToShowHelp;
  1177. if (SplitCommand.existskey(1)) CommandToShowHelp = SplitCommand[1];
  1178.  
  1179. // Show help for specified command
  1180. if (C_GroupCommandsHelp.existskey(CommandToShowHelp))
  1181. ComposedMessage = C_GroupCommandsHelp[CommandToShowHelp];
  1182.  
  1183. // Show help for the formatted message command
  1184. else if (C_ChatMessageCommands.existskey(CommandToShowHelp))
  1185. ComposedMessage = "/"^CommandToShowHelp^" "^C_GroupCommandsHelp["/chatmsg"];
  1186.  
  1187. // Show list of all available commands
  1188. else {
  1189. ComposedMessage = "Available commands: ";
  1190. declare Text[] AllCommands;
  1191.  
  1192. foreach (Command => Help in C_GroupCommandsHelp) if (Command != "/chatmsg") AllCommands.add(Command);
  1193. foreach (Command => Message in C_ChatMessageCommands) AllCommands.add(Command);
  1194. AllCommands = AllCommands.sort();
  1195.  
  1196. foreach (I => Command in AllCommands) {
  1197. if (I > 0) ComposedMessage ^= ", ";
  1198. ComposedMessage ^= Command;
  1199. }
  1200. ComposedMessage ^= ".";
  1201. }
  1202.  
  1203. // Send message to buddy
  1204. if (_CommandPerformer == LocalUser.Login) NewReceivedMessages.add(["*group*", "", C_GroupFormatInfo^ComposedMessage]);
  1205. else BuddiesManager.SendMessage(Buddy, "", C_GroupFormatInfo^ComposedMessage);
  1206. return;
  1207. }
  1208. // ---------------------------------- //
  1209. // Me
  1210. case "me" : {
  1211. // User is muted
  1212. if (Persistent_Evidence_MutedGroupBuddies.exists(_CommandPerformer))
  1213. ExceptionMessage = "You're muted in this group!";
  1214.  
  1215. // Send message
  1216. else if (SplitCommand.existskey(1)) {
  1217. declare Text CommandText;
  1218. foreach (I => Word in SplitCommand) if (I > 0) CommandText ^= Word^" ";
  1219. SendMessageToGroup("", C_GroupFormatInfo^"$<"^UserName^"$> $i"^CommandText);
  1220. return;
  1221. }
  1222.  
  1223. // Missing parameters
  1224. else ExceptionMessage = "Usage: /me [message]";
  1225. }
  1226. // ---------------------------------- //
  1227. // Create list
  1228. case "list" : {
  1229. declare OutputMessage = C_GroupFormatInfo;
  1230. declare Text ListType;
  1231. if (SplitCommand.existskey(1)) ListType = SplitCommand[1];
  1232.  
  1233. switch (ListType) {
  1234. // ---------------------------------- //
  1235. // Banned users list
  1236. case "ban" : {
  1237. OutputMessage ^= "Banned users ("^Persistent_Evidence_GroupBannedUsers.count^"): ";
  1238. foreach (I => Login in Persistent_Evidence_GroupBannedUsers) {
  1239. if (I > 0) OutputMessage ^= ", ";
  1240. OutputMessage ^= Login;
  1241. }
  1242. }
  1243. // ---------------------------------- //
  1244. // Muted users list
  1245. case "muted" : {
  1246. OutputMessage ^= "Muted users ("^Persistent_Evidence_MutedGroupBuddies.count^"): ";
  1247. foreach (I => Login in Persistent_Evidence_MutedGroupBuddies) {
  1248. if (I > 0) OutputMessage ^= ", ";
  1249. OutputMessage ^= Login;
  1250. }
  1251. }
  1252. // ---------------------------------- //
  1253. // Operators list
  1254. case "op" : {
  1255. OutputMessage ^= "Group operators ("^1 + Persistent_Evidence_GroupOperators.count^"): "^LocalUser.Login;
  1256. foreach (I => Login in Persistent_Evidence_GroupOperators) OutputMessage ^= ", "^Login;
  1257. }
  1258. // ---------------------------------- //
  1259. // Operators list
  1260. case "nf" : {
  1261. OutputMessage ^= "Users that disabled \"noformat\" option ("^Persistent_Evidence_DisabledNoformat.count^"): ";
  1262. foreach (I => Login in Persistent_Evidence_DisabledNoformat) {
  1263. if (I > 0) OutputMessage ^= ", ";
  1264. OutputMessage ^= Login;
  1265. }
  1266. }
  1267. // ---------------------------------- //
  1268. // List of all available logins to format name
  1269. case "logins" : {
  1270. declare Text[] AvailableLogins;
  1271. foreach (Buddy in BuddiesManager.Buddies) AvailableLogins.add(Buddy.Login);
  1272. foreach (Buddy in BuddiesManager.IncomingBuddyRequests) AvailableLogins.add(Buddy.Login);
  1273. foreach (Buddy in BuddiesManager.OutgoingBuddyRequests) AvailableLogins.add(Buddy.Login);
  1274. AvailableLogins = AvailableLogins.sort();
  1275.  
  1276. OutputMessage ^= "Available logins ("^1 + AvailableLogins.count^"): "^LocalUser.Login;
  1277. foreach (I => Login in AvailableLogins) OutputMessage ^= ", "^Login;
  1278. }
  1279. // ---------------------------------- //
  1280. // Connected users list
  1281. default : {
  1282. OutputMessage ^= "Users online ("^1 + Persistent_Evidence_BuddiesInGroup.count^"): "^LocalUser.Login;
  1283. foreach (Login in Persistent_Evidence_BuddiesInGroup) OutputMessage ^= ", "^Login;
  1284. }
  1285. }
  1286.  
  1287. // Display list on user screen
  1288. if (_CommandPerformer == LocalUser.Login) NewReceivedMessages.add(["*group*", "", OutputMessage]);
  1289. else BuddiesManager.SendMessage(Buddy, "", OutputMessage);
  1290. return;
  1291. }
  1292. // ---------------------------------- //
  1293. // Kick user
  1294. case "kick" : {
  1295. declare Text ExceptionMessage;
  1296. if (SplitCommand.existskey(1) && SplitCommand[1] != "") {
  1297. declare LoginToMute = SplitCommand[1];
  1298.  
  1299. // User tried to kick host
  1300. if (LoginToMute == LocalUser.Login) ExceptionMessage = "Requested user is the host!";
  1301.  
  1302. // User is not connected
  1303. else if (!Persistent_Evidence_BuddiesInGroup.exists(LoginToMute))
  1304. ExceptionMessage = "User not found!";
  1305.  
  1306. // Operator tries to kick another operator
  1307. else if (GetUserPermissionsLevel(_CommandPerformer) <= 1 && GetUserPermissionsLevel(LoginToMute) >= 1)
  1308. ExceptionMessage = "You can't kick other operators!";
  1309.  
  1310. // Kick specified user
  1311. else {
  1312. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> kicked $<"^GetNameFromLogin(LoginToMute)^"$>!");
  1313. PerformChatCommand(LoginToMute, "/quit");
  1314. return;
  1315. }
  1316. }
  1317. // Login not specified
  1318. else ExceptionMessage = "Usage: /kick [login]";
  1319. }
  1320. // ---------------------------------- //
  1321. // Ban user
  1322. case "ban" : {
  1323. if (SplitCommand.existskey(1) && SplitCommand[1] != "") {
  1324. declare LoginToBan = SplitCommand[1];
  1325.  
  1326. // User tried to ban host
  1327. if (LoginToBan == LocalUser.Login) ExceptionMessage = "Requested user is the host!";
  1328.  
  1329. // User is not connected
  1330. else if (!Persistent_Evidence_BuddiesInGroup.exists(LoginToBan))
  1331. ExceptionMessage = "User not found!";
  1332.  
  1333. // User is already banned
  1334. else if (Persistent_Evidence_GroupBannedUsers.exists(LoginToBan))
  1335. ExceptionMessage = "Requested user is already banned!";
  1336.  
  1337. // Operator tries to ban another operator
  1338. else if (GetUserPermissionsLevel(_CommandPerformer) <= 1 && GetUserPermissionsLevel(LoginToBan) >= 1)
  1339. ExceptionMessage = "You can't ban other operators!";
  1340.  
  1341. // Ban specified user
  1342. else {
  1343. Persistent_Evidence_GroupBannedUsers.add(LoginToBan);
  1344. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> banned $<"^GetNameFromLogin(LoginToBan)^"$>!");
  1345. PerformChatCommand(LoginToBan, "/quit");
  1346. return;
  1347. }
  1348. }
  1349. // Login not specified
  1350. else ExceptionMessage = "Usage: /ban [login]";
  1351. }
  1352. // ---------------------------------- //
  1353. // Unban user
  1354. case "unban" : {
  1355. if (SplitCommand.existskey(1) && SplitCommand[1] != "") {
  1356. declare LoginToUnban = SplitCommand[1];
  1357.  
  1358. // User tried to ban host
  1359. if (LoginToUnban == LocalUser.Login) ExceptionMessage = "Requested user is the host!";
  1360.  
  1361. // User is not banned
  1362. else if (!Persistent_Evidence_GroupBannedUsers.exists(LoginToUnban))
  1363. ExceptionMessage = "Requested user is not banned!";
  1364.  
  1365. // Operator tries to unban another operator
  1366. else if (GetUserPermissionsLevel(_CommandPerformer) <= 1 && GetUserPermissionsLevel(LoginToUnban) >= 1)
  1367. ExceptionMessage = "You can't unban other operators!";
  1368.  
  1369. // Unban specified user
  1370. else {
  1371. declare Removed = Persistent_Evidence_GroupBannedUsers.remove(LoginToUnban);
  1372. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> unbanned $<"^GetNameFromLogin(LoginToUnban)^"$>!");
  1373. return;
  1374. }
  1375. }
  1376. // Login not specified
  1377. else ExceptionMessage = "Usage: /unban [login]";
  1378. }
  1379. // ---------------------------------- //
  1380. // Mute user
  1381. case "mute" : {
  1382. if (SplitCommand.existskey(1) && SplitCommand[1] != "") {
  1383. declare LoginToMute = SplitCommand[1];
  1384.  
  1385. // User tried to mute host
  1386. if (LoginToMute == LocalUser.Login) ExceptionMessage = "Requested user is the host!";
  1387.  
  1388. // User is not connected
  1389. else if (!Persistent_Evidence_BuddiesInGroup.exists(LoginToMute))
  1390. ExceptionMessage = "User not found!";
  1391.  
  1392. // User is already muted
  1393. else if (Persistent_Evidence_MutedGroupBuddies.exists(LoginToMute))
  1394. ExceptionMessage = "Requested user is already muted!";
  1395.  
  1396. // Operator tries to mute another operator
  1397. else if (GetUserPermissionsLevel(_CommandPerformer) <= 1 && GetUserPermissionsLevel(LoginToMute) >= 1)
  1398. ExceptionMessage = "You can't mute other operators!";
  1399.  
  1400. // Mute specified user
  1401. else {
  1402. Persistent_Evidence_MutedGroupBuddies.add(LoginToMute);
  1403. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> muted $<"^GetNameFromLogin(LoginToMute)^"$>!");
  1404. return;
  1405. }
  1406. }
  1407. // Login not specified
  1408. else ExceptionMessage = "Usage: /mute [login]";
  1409. }
  1410. // ---------------------------------- //
  1411. // Unmute user
  1412. case "unmute" : {
  1413. if (SplitCommand.existskey(1) && SplitCommand[1] != "") {
  1414. declare LoginToUnmute = SplitCommand[1];
  1415.  
  1416. // User tried to mute host
  1417. if (LoginToUnmute == LocalUser.Login) ExceptionMessage = "Requested user is the host!";
  1418.  
  1419. // User is not muted
  1420. else if (!Persistent_Evidence_MutedGroupBuddies.exists(LoginToUnmute))
  1421. ExceptionMessage = "Requested user is not muted!";
  1422.  
  1423. // Operator tries to unmute another operator
  1424. else if (GetUserPermissionsLevel(_CommandPerformer) <= 1 && GetUserPermissionsLevel(LoginToUnmute) >= 1)
  1425. ExceptionMessage = "You can't unmute other operators!";
  1426.  
  1427. // Unmute specified user
  1428. else {
  1429. declare Removed = Persistent_Evidence_MutedGroupBuddies.remove(LoginToUnmute);
  1430. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> unmuted $<"^GetNameFromLogin(LoginToUnmute)^"$>!");
  1431. return;
  1432. }
  1433. }
  1434. // Login not specified
  1435. else ExceptionMessage = "Usage: /unmute [login]";
  1436. }
  1437. // ---------------------------------- //
  1438. // Give operator rights
  1439. case "addop" : {
  1440. if (SplitCommand.existskey(1) && SplitCommand[1] != "") {
  1441. declare LoginToSetOp = SplitCommand[1];
  1442.  
  1443. // User tried to give host operator rights
  1444. if (LoginToSetOp == LocalUser.Login) ExceptionMessage = "Requested user is the host!";
  1445.  
  1446. // User is not connected
  1447. else if (!Persistent_Evidence_BuddiesInGroup.exists(LoginToSetOp))
  1448. ExceptionMessage = "User not found!";
  1449.  
  1450. // User already is operator
  1451. else if (GetUserPermissionsLevel(LoginToSetOp) >= 1)
  1452. ExceptionMessage = "Requested user already has operator rights!";
  1453.  
  1454. // Give operator rights
  1455. else {
  1456. Persistent_Evidence_GroupOperators.add(LoginToSetOp);
  1457. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> gave $<"^GetNameFromLogin(LoginToSetOp)^"$> operator rights!");
  1458. return;
  1459. }
  1460. }
  1461. // Login not specified
  1462. else ExceptionMessage = "Usage: /addop [login]";
  1463. }
  1464. // ---------------------------------- //
  1465. // Unmute
  1466. case "removeop" : {
  1467. if (SplitCommand.existskey(1) && SplitCommand[1] != "") {
  1468. declare LoginToRemoveOp = SplitCommand[1];
  1469.  
  1470. // User tried to remove operator rights from host
  1471. if (LoginToRemoveOp == LocalUser.Login) ExceptionMessage = "Requested user is the host!";
  1472.  
  1473. // User is not operator
  1474. else if (GetUserPermissionsLevel(LoginToRemoveOp) < 1)
  1475. ExceptionMessage = "Requested user is not operator!";
  1476.  
  1477. // Remove operator rights
  1478. else {
  1479. declare Removed = Persistent_Evidence_GroupOperators.remove(LoginToRemoveOp);
  1480. SendMessageToGroup("", C_GroupFormatSuccess^UserLevelName^" $<"^UserName^"$> took operator rights from $<"^GetNameFromLogin(LoginToRemoveOp)^"$>!");
  1481. return;
  1482. }
  1483. }
  1484. // Login not specified
  1485. else ExceptionMessage = "Usage: /removeop [login]";
  1486. }
  1487. // ---------------------------------- //
  1488. // Send private message
  1489. case "pm" : {
  1490. if (SplitCommand.existskey(2)) {
  1491. declare MessageRecipient = SplitCommand[1];
  1492.  
  1493. // Sender is muted
  1494. if (Persistent_Evidence_MutedGroupBuddies.exists(_CommandPerformer))
  1495. ExceptionMessage = "You're muted in this group!";
  1496.  
  1497. // User is sending message to himself
  1498. else if (MessageRecipient == _CommandPerformer)
  1499. ExceptionMessage = "You can't send private messages to yourself!";
  1500.  
  1501. // User not found
  1502. else if (!Persistent_Evidence_BuddiesInGroup.exists(MessageRecipient) && MessageRecipient != LocalUser.Login)
  1503. ExceptionMessage = "User not found!";
  1504.  
  1505. // Send message
  1506. else {
  1507. declare Text ComposedMessage;
  1508. foreach (I => Word in SplitCommand) if (I >= 2) ComposedMessage ^= " "^Word;
  1509.  
  1510. // Sender message
  1511. declare SenderMessageText = C_GroupFormatPrivate^"[To $<"^GetNameFromLogin(MessageRecipient)^"$>]"^ComposedMessage;
  1512. if (_CommandPerformer != LocalUser.Login) BuddiesManager.SendMessage(Buddy, "", SenderMessageText);
  1513. else NewReceivedMessages.add(["*group*", LocalUser.Login, SenderMessageText]);
  1514.  
  1515. // Receipent message
  1516. declare RecipientMessageText = C_GroupFormatPrivate^"[From $<"^UserName^"$>]"^ComposedMessage;
  1517. if (MessageRecipient == LocalUser.Login) NewReceivedMessages.add(["*group*", _CommandPerformer, RecipientMessageText]);
  1518. else BuddiesManager.SendMessage(BuddiesManager.GetBuddyFromLogin(MessageRecipient), "", RecipientMessageText);
  1519.  
  1520. // Save latest message sender
  1521. Persistent_Evidence_LastPMLogins[_CommandPerformer] = MessageRecipient;
  1522. Persistent_Evidence_LastPMLogins[MessageRecipient] = _CommandPerformer;
  1523. return;
  1524. }
  1525. }
  1526.  
  1527. // Message not specified
  1528. else if (SplitCommand.existskey(1))
  1529. ExceptionMessage = "Usage: /pm "^SplitCommand[1]^" [message]";
  1530.  
  1531. // Login not specified
  1532. else ExceptionMessage = "Usage: /pm [login] [message]";
  1533. }
  1534. // ---------------------------------- //
  1535. // Reply to latest private message
  1536. case "pmr" : {
  1537. if (SplitCommand.existskey(1)) {
  1538. // Sender is muted
  1539. if (Persistent_Evidence_MutedGroupBuddies.exists(_CommandPerformer))
  1540. ExceptionMessage = "You're muted in this group!";
  1541.  
  1542. // User hasn't contacted anyone yet
  1543. if (!Persistent_Evidence_LastPMLogins.existskey(_CommandPerformer))
  1544. ExceptionMessage = "You haven't started any private conversation yet!";
  1545.  
  1546. // Send message
  1547. else {
  1548. declare Text ComposedMessage;
  1549. foreach (I => Word in SplitCommand) if (I >= 1) ComposedMessage ^= " "^Word;
  1550. declare Recipient = Persistent_Evidence_LastPMLogins[_CommandPerformer];
  1551. PerformChatCommand(_CommandPerformer, "/pm "^Recipient^ComposedMessage);
  1552. return;
  1553. }
  1554. }
  1555.  
  1556. // Message not specified
  1557. else ExceptionMessage = "Usage: /pmr [message]";
  1558. }
  1559. // ---------------------------------- //
  1560. // Set noformat option
  1561. case "noformat" : {
  1562. declare PrevNoformatSetting = !Persistent_Evidence_DisabledNoformat.exists(_CommandPerformer);
  1563. declare Text InformationMessage;
  1564.  
  1565. if (SplitCommand.existskey(1)) {
  1566. declare NewSettingValue = SplitCommand[1] == "1";
  1567.  
  1568. // Invalid value
  1569. if (SplitCommand[1] != "0" && SplitCommand[1] != "1")
  1570. ExceptionMessage = "Only accepted boolean values are \"0\" and \"1\"!";
  1571.  
  1572. // New setting is the same
  1573. else if (NewSettingValue == PrevNoformatSetting)
  1574. ExceptionMessage = "Option \"noformat\" is already set to \""^NewSettingValue^"\"!";
  1575.  
  1576. // Change setting
  1577. else {
  1578. InformationMessage = C_GroupFormatInfo^"Option \"noformat\" has been set to \""^NewSettingValue^"\"!";
  1579. if (!PrevNoformatSetting) {
  1580. declare Removed = Persistent_Evidence_DisabledNoformat.remove(_CommandPerformer);
  1581. } else
  1582. Persistent_Evidence_DisabledNoformat.add(_CommandPerformer);
  1583. }
  1584. }
  1585.  
  1586. // Setting not specified
  1587. else InformationMessage = C_GroupFormatInfo^"Option \"noformat\" is set to \""^PrevNoformatSetting^"\".";
  1588.  
  1589. if (InformationMessage != "") {
  1590. if (_CommandPerformer != LocalUser.Login) BuddiesManager.SendMessage(Buddy, "", InformationMessage);
  1591. else NewReceivedMessages.add(["*group*", "", InformationMessage]);
  1592. return;
  1593. }
  1594. }
  1595. // ---------------------------------- //
  1596. // Show script information
  1597. case "core" : {
  1598. declare ComposedMessage = ScriptName^" v"^ScriptVersionNb^" @"^ScriptVersion;
  1599. if (_CommandPerformer != LocalUser.Login) BuddiesManager.SendMessage(Buddy, "", C_GroupFormatInfo^ComposedMessage);
  1600. else NewReceivedMessages.add(["*group*", "", C_GroupFormatInfo^ComposedMessage]);
  1601. return;
  1602. }
  1603. // ---------------------------------- //
  1604. // Ragequit
  1605. case "rq" : {
  1606. if (_CommandPerformer != LocalUser.Login) {
  1607. SendMessageToGroup("", "$F00$<"^UserName^"$> $isaid !@#$$% and ragequit.");
  1608. PerformChatCommand(_CommandPerformer, "/quit");
  1609. return;
  1610. }
  1611. // Host tries to leave
  1612. else ExceptionMessage = "You're the host!";
  1613. }
  1614. // ---------------------------------- //
  1615. // Bootme
  1616. case "bm" : {
  1617. if (_CommandPerformer != LocalUser.Login) {
  1618. SendMessageToGroup("", C_GroupFormatInfo^"$<"^UserName^"$> $ichooses to boot back to the real world!");
  1619. PerformChatCommand(_CommandPerformer, "/quit");
  1620. return;
  1621. }
  1622. // Host tries to leave
  1623. else ExceptionMessage = "You're the host!";
  1624. }
  1625. }
  1626.  
  1627. // ---------------------------------- //
  1628. // Formatted chat messages
  1629. if (C_ChatMessageCommands.existskey(CommandType)) {
  1630. if (!Persistent_Evidence_MutedGroupBuddies.exists(_CommandPerformer)) {
  1631. declare ComposedMessage = "$i"^C_ChatMessageCommands[CommandType];
  1632.  
  1633. // Attach additional username
  1634. if (SplitCommand.existskey(1) && SplitCommand[1] != "" && C_ChatMessageWithLogin.exists(CommandType))
  1635. ComposedMessage ^= " $i$<"^GetNameFromLogin(SplitCommand[1])^"$>$i";
  1636.  
  1637. ComposedMessage ^= "!";
  1638. SendMessageToGroup(_CommandPerformer, ComposedMessage);
  1639. return;
  1640. }
  1641.  
  1642. // User is muted
  1643. else ExceptionMessage = "You're muted in this group!";
  1644. }
  1645.  
  1646. // ---------------------------------- //
  1647. // Command unknown
  1648. if (ExceptionMessage == "") ExceptionMessage = "Command unknown";
  1649.  
  1650. // ---------------------------------- //
  1651. // Show exception message
  1652. if (_CommandPerformer != LocalUser.Login) BuddiesManager.SendMessage(Buddy, "", C_GroupFormatError^ExceptionMessage);
  1653. else NewReceivedMessages.add(["*group*", "", C_GroupFormatError^ExceptionMessage]);
  1654. }
  1655.  
  1656. // ---------------------------------- //
  1657. /** Format URL from given base and query
  1658. *
  1659. * @param _URL Base of the URL
  1660. * @param _Query Elements of the query
  1661. *
  1662. * @return Complete URL
  1663. */
  1664. Text FormatURL(Text _URL, Text[Text] _Query) {
  1665. if (_URL == "" || !Http.IsValidUrl(_URL)) return "";
  1666. declare Text QueryText;
  1667. declare I = 0;
  1668.  
  1669. foreach (Name => Value in _Query) {
  1670. if (I == 0) QueryText ^= "?";
  1671. else QueryText ^= "&";
  1672. QueryText ^= TL::URLEncode(Name)^"="^TL::URLEncode(Value);
  1673. I += 1;
  1674. }
  1675.  
  1676. return _URL^QueryText;
  1677. }
  1678.  
  1679. // ---------------------------------- //
  1680. /** Load users list and data from request XML result
  1681. *
  1682. * @param _Document XML document with users data
  1683. */
  1684. Void LoadUsersData(CXmlDocument _Document) {
  1685. if (_Document == Null || _Document.Root == Null || _Document.Root.Name != "users") return;
  1686.  
  1687. // ---------------------------------- //
  1688. // Get manialink layer
  1689. declare WindowLayer = GetLayerFromId("WindowLayer");
  1690. if (WindowLayer == Null) return;
  1691.  
  1692. declare WindowPage <=> WindowLayer.LocalPage;
  1693. if (WindowPage == Null) return;
  1694.  
  1695. // ---------------------------------- //
  1696. // Share variables with manialink
  1697. declare Text[] BuddiesList_GlobalList for WindowPage;
  1698. declare Text[Text] GlobalChat_BuddiesName for WindowPage;
  1699. declare Integer[Text] GlobalChat_BuddiesPresenceId for WindowPage;
  1700. declare Text[Text] GlobalChat_BuddiesStatus for WindowPage;
  1701.  
  1702. // Clear previous data
  1703. BuddiesList_GlobalList.clear();
  1704.  
  1705. declare LocalUserExists = False;
  1706.  
  1707. // ---------------------------------- //
  1708. // Read nodes data
  1709. foreach (Node in _Document.Root.Children) {
  1710. if (Node.Name == "user") {
  1711. // Get user Login
  1712. declare UserLogin = Node.GetAttributeText("login", "");
  1713. if (UserLogin != "" && UserLogin != LocalUser.Login) {
  1714. BuddiesList_GlobalList.add(UserLogin);
  1715.  
  1716. // Get user name
  1717. declare UserName = Node.GetAttributeText("name", "");
  1718. if (UserName != "") GlobalChat_BuddiesName[UserLogin] = UserName;
  1719.  
  1720. // Get user presence id
  1721. declare UserPresenceId = Node.GetAttributeInteger("presenceid", 0);
  1722. if (UserPresenceId < 1 || UserPresenceId > 5) UserPresenceId = 1;
  1723. GlobalChat_BuddiesPresenceId[UserLogin] = UserPresenceId;
  1724.  
  1725. // Get user status
  1726. declare UserStatus = Node.GetAttributeText("status", "");
  1727. if (UserStatus == "") UserStatus = C_UserPresenceStatus[UserPresenceId];
  1728. GlobalChat_BuddiesStatus[UserLogin] = UserStatus;
  1729. }
  1730.  
  1731. if (UserLogin == LocalUser.Login) LocalUserExists = True;
  1732. }
  1733. }
  1734.  
  1735. // Trigegr connection error
  1736. if (!LocalUserExists) G_GlobalChat_ConnectionError = True;
  1737. }
  1738.  
  1739. // ---------------------------------- //
  1740. /** Load messages data from request XML result
  1741. *
  1742. * @param _Document XML document with messages data
  1743. */
  1744. Void LoadMessages(CXmlDocument _Document) {
  1745. if (_Document == Null || _Document.Root == Null || _Document.Root.Name != "messages") return;
  1746.  
  1747. // ---------------------------------- //
  1748. // Get manialink layer
  1749. declare WindowLayer = GetLayerFromId("WindowLayer");
  1750. if (WindowLayer == Null) return;
  1751.  
  1752. declare WindowPage <=> WindowLayer.LocalPage;
  1753. if (WindowPage == Null) return;
  1754.  
  1755. // ---------------------------------- //
  1756. // Share variables with manialink
  1757. declare Text[][] NewReceivedMessages for WindowPage;
  1758.  
  1759. // ---------------------------------- //
  1760. // Read nodes data
  1761. foreach (Node in _Document.Root.Children) {
  1762. if (Node.Name == "msg") {
  1763. // Get user Login
  1764. declare UserLogin = Node.GetAttributeText("author", "");
  1765.  
  1766. // Get message timestamp
  1767. declare Timestamp = Node.GetAttributeInteger("timestamp", 0);
  1768.  
  1769. // Get umessage body
  1770. declare MessageBody = Node.GetAttributeText("body", "");
  1771.  
  1772. if (UserLogin != "" && Timestamp > 0 && MessageBody != "") {
  1773. if (!G_GlobalChat_ReceivedMessages.exists(Timestamp)) {
  1774. G_GlobalChat_ReceivedMessages.add(Timestamp);
  1775. NewReceivedMessages.add(["*global*", UserLogin, MessageBody]);
  1776. }
  1777. }
  1778. }
  1779. }
  1780. }
  1781.  
  1782. // ---------------------------------- //
  1783. /** Create widget manialink
  1784. *
  1785. * @return The manialink
  1786. */
  1787. Text CreateManialinkPluginIcon() {
  1788. return """
  1789. <manialink version="2" name="Evidence:PluginIcon">
  1790. <!-- Plugin icon frame -->
  1791. <frame id="Frame_EvidencPluginIcon" posn="-8 90 1">
  1792. <quad sizen="9.5 6" halign="right" bgcolor="0AF" opacity="0" id="Quad_PluginIconBgCard" ScriptEvents="1"/>
  1793. <quad posn="-7 .25 1" sizen="6 6" colorize="FFF" image="http://i.imgur.com/zWESBiR.png"/>
  1794. <label posn="-7.5 -3 1" halign="right" valign="center2" textsize="2" textemboss="1" textcolor="FFF" id="Label_PluginIconUsers"/>
  1795.  
  1796. <!-- Plugin icon notifications amount -->
  1797. <frame id="Frame_PluginIconNotice" posn="-2 -1.5 2" hidden="1">
  1798. <quad sizen="2.5 2.5" halign="center" valign="center" image="file://Media/Manialinks/Common/disc.dds" colorize="B00"/>
  1799. <label posn="0 0 1" halign="center" valign="center2" style="TextValueSmallSm" scale=".45" textcolor="FFF" id="Label_PluginIconNotice"/>
  1800. </frame>
  1801. </frame>
  1802. <script><!--
  1803. /**
  1804. * EVIDENCE by domino54
  1805. * Plugin icon manialink
  1806. */
  1807.  
  1808. #Include "TextLib" as TL
  1809.  
  1810. // ---------------------------------- //
  1811. // Start manialink
  1812. // ---------------------------------- //
  1813. ***StartManialink***
  1814. ***
  1815. // ---------------------------------- //
  1816. // Load interface elements
  1817. declare Quad_PluginIconBgCard <=> (Page.GetFirstChild("Quad_PluginIconBgCard") as CMlQuad);
  1818. declare Label_PluginIconUsers <=> (Page.GetFirstChild("Label_PluginIconUsers") as CMlLabel);
  1819. declare Frame_PluginIconNotice <=> (Page.GetFirstChild("Frame_PluginIconNotice") as CMlFrame);
  1820. declare Label_PluginIconNotice <=> (Page.GetFirstChild("Label_PluginIconNotice") as CMlLabel);
  1821.  
  1822. // ---------------------------------- //
  1823. // Plugin script communication
  1824. declare PluginNbUsersOnline for Page = 0; ///< Amount of buddies online
  1825. declare PluginNbUnreadMessages for Page = 0; ///< Amount of unread messages from buddies and group
  1826. declare PluginIsChatWindowOpen for Page = False; ///< Current chat visibility status
  1827. declare PluginTriggerOpenChat for Page = False; ///< Trigger chat visibility
  1828.  
  1829. /// Update variables
  1830. declare PrevNbBuddiesOnline = -1;
  1831. ***
  1832.  
  1833. // ---------------------------------- //
  1834. // Yield
  1835. // ---------------------------------- //
  1836. ***Yield***
  1837. ***
  1838. // ---------------------------------- //
  1839. // Events management
  1840. foreach (Event in PendingEvents) {
  1841. // ---------------------------------- //
  1842. // Mouse click
  1843. if (Event.Type == CMlEvent::Type::MouseClick) {
  1844. if (Event.ControlId == "Quad_PluginIconBgCard") {
  1845. PluginTriggerOpenChat = True;
  1846. Audio.PlaySoundEvent(CAudioManager::ELibSound::Valid, 1, 0.);
  1847. }
  1848. }
  1849. // ---------------------------------- //
  1850. // Mouse over
  1851. if (Event.Type == CMlEvent::Type::MouseOver) {
  1852. if (Event.ControlId == "Quad_PluginIconBgCard") Quad_PluginIconBgCard.Opacity = .5;
  1853. }
  1854. // ---------------------------------- //
  1855. // Mouse out
  1856. if (Event.Type == CMlEvent::Type::MouseOut) {
  1857. if (Event.ControlId == "Quad_PluginIconBgCard") Quad_PluginIconBgCard.Opacity = 0.;
  1858. }
  1859. }
  1860.  
  1861. // ---------------------------------- //
  1862. // Show amount of connected buddies
  1863. if (PrevNbBuddiesOnline != PluginNbUsersOnline) {
  1864. PrevNbBuddiesOnline = PluginNbUsersOnline;
  1865. Label_PluginIconUsers.SetText(TL::ToText(PluginNbUsersOnline));
  1866. Quad_PluginIconBgCard.Size.X = 9.5 + Label_PluginIconUsers.ComputeWidth(Label_PluginIconUsers.Value);
  1867. }
  1868.  
  1869. // ---------------------------------- //
  1870. // Show amount of unread messages
  1871. Frame_PluginIconNotice.Visible = (!PluginIsChatWindowOpen && PluginNbUnreadMessages > 0);
  1872. if (Frame_PluginIconNotice.Visible) {
  1873. Label_PluginIconNotice.Value = TL::ToText(PluginNbUnreadMessages);
  1874. }
  1875. ***
  1876.  
  1877. // ---------------------------------- //
  1878. // Main
  1879. // ---------------------------------- //
  1880. main() {
  1881. +++StartManialink+++
  1882. while (True) {
  1883. +++Yield+++
  1884. yield;
  1885. }
  1886. }
  1887. --></script>
  1888. </manialink>""";
  1889. }
  1890.  
  1891. // ---------------------------------- //
  1892. /** Create dialog box manialink
  1893. *
  1894. * @return The manialink
  1895. */
  1896. Text CreateManialinkDialogBox() {
  1897. return """
  1898. <manialink version="2" name="Evidence:DialogBox" background="0">
  1899. <frame id="Frame_DialogBox" posn="0 0 70" hidden="1">
  1900. <quad posn="0 0 -1" sizen="320 180" halign="center" valign="center" style="Bgs1" substyle="BgDialogBlur" ScriptEvents="1"/>
  1901. <quad posn="0 17 1" sizen="126.5 8" halign="center" style="Bgs1InRace" substyle="BgGlow2"/>
  1902. <quad sizen="120 25" halign="center" valign="center" style="Bgs1InRace" substyle="BgWindow2"/>
  1903. <quad posn="0 -12 1" sizen="120 2" halign="center" style="Bgs1InRace" substyle="BgMetalBar"/>
  1904.  
  1905. <label posn="0 6.25" sizen="100 4" halign="center" valign="center2" textsize="2" textcolor="FFF" autonewline="1" id="Label_DialogMessage"/>
  1906. <label posn="-32 -4 1" style="CardButtonMedium" valign="center" halign="center" text="Remove" translate="1" id="Label_ButtonRemove" ScriptEvents="1"/>
  1907. <label posn="32 -4 1" style="CardButtonMedium" valign="center" halign="center" text="Cancel" translate="1" id="Label_ButtonCancel" ScriptEvents="1"/>
  1908. </frame>
  1909.  
  1910. <script><!--
  1911. /**
  1912. * EVIDENCE by domino54
  1913. * Buddy removal dialog box
  1914. */
  1915.  
  1916. #Include "TextLib" as TL
  1917.  
  1918. // ---------------------------------- //
  1919. // Main
  1920. // ---------------------------------- //
  1921. ***Main***
  1922. ***
  1923. // ---------------------------------- //
  1924. // Load interface elements
  1925. declare Frame_DialogBox <=> (Page.GetFirstChild("Frame_DialogBox") as CMlFrame);
  1926. declare Label_DialogMessage <=> (Page.GetFirstChild("Label_DialogMessage") as CMlLabel);
  1927.  
  1928. // ---------------------------------- //
  1929. // Script communication
  1930. declare DialogVisible for Page = False; ///< Visibility of the dialog box
  1931. declare DialogBuddyLogin for Page = ""; ///< Login of the buddy to remove
  1932. declare DialogBuddyName for Page = ""; ///< Name of the buddy to remove
  1933.  
  1934. /// Update variables
  1935. declare PrevDialogVisible = False;
  1936. ***
  1937.  
  1938. // ---------------------------------- //
  1939. // Yield
  1940. // ---------------------------------- //
  1941. ***Yield***
  1942. ***
  1943. // ---------------------------------- //
  1944. // Events management
  1945. foreach (Event in PendingEvents) {
  1946. // ---------------------------------- //
  1947. // Click on the interface element
  1948. if (Event.Type == CMlEvent::Type::MouseClick) {
  1949. // ---------------------------------- //
  1950. // Button remove
  1951. if (Event.ControlId == "Label_ButtonRemove") {
  1952. SendCustomEvent("BuddyRemoved", [DialogBuddyLogin]);
  1953. DialogVisible = False;
  1954. }
  1955. // ---------------------------------- //
  1956. // Button cancel
  1957. if (Event.ControlId == "Label_ButtonCancel") DialogVisible = False;
  1958. }
  1959. // ---------------------------------- //
  1960. // Menu navigation
  1961. if (Event.Type == CMlEvent::Type::MenuNavigation) {
  1962. // ---------------------------------- //
  1963. // Escape key
  1964. if (Event.MenuNavAction == CMlEvent::EMenuNavAction::Cancel) DialogVisible = False;
  1965. }
  1966. }
  1967.  
  1968. // ---------------------------------- //
  1969. // Update visibility
  1970. if (PrevDialogVisible != DialogVisible) {
  1971. PrevDialogVisible = DialogVisible;
  1972. EnableMenuNavigation(DialogVisible, True, Null, 10);
  1973.  
  1974. // ---------------------------------- //
  1975. // Set visibility
  1976. Frame_DialogBox.Visible = DialogVisible;
  1977.  
  1978. // ---------------------------------- //
  1979. // Play sound
  1980. declare TargetSound = CAudioManager::ELibSound::HideDialog;
  1981. if (DialogVisible) TargetSound = CAudioManager::ELibSound::ShowDialog;
  1982. Audio.PlaySoundEvent(TargetSound, 0, 0.);
  1983.  
  1984. // ---------------------------------- //
  1985. // Set buddy name
  1986. if (DialogVisible) Label_DialogMessage.SetText(TL::Compose(_("Are you sure you want to remove $<%1$> from your buddy list?"), DialogBuddyName));
  1987. }
  1988. ***
  1989.  
  1990. // ---------------------------------- //
  1991. // Main
  1992. // ---------------------------------- //
  1993. main() {
  1994. +++Main+++
  1995. while (True) {
  1996. yield;
  1997. +++Yield+++
  1998. }
  1999. }
  2000. --></script>
  2001. </manialink>""";
  2002. }
  2003.  
  2004. // ---------------------------------- //
  2005. /** Create window manialink
  2006. *
  2007. * @return The manialink
  2008. */
  2009. Text CreateManialinkWindow() {
  2010. return """
  2011. <?xml version="1.0" encoding="utf-8" standalone="yes"?>
  2012. <manialink version="2" name="Evidence:ChatWindow" background="0">
  2013. <stylesheet>
  2014. <style id="Quad_BuddySlotBtnJoin" image="{{{C_ImgBase}}}buddy-join.dds" imagefocus="{{{C_ImgBase}}}buddy-join-on.dds"/>
  2015. <style id="Quad_BuddySlotBtnAdd" image="{{{C_ImgBase}}}buddy-buddy-accept.dds" imagefocus="{{{C_ImgBase}}}buddy-buddy-accept-focus.dds"/>
  2016. <style id="Quad_BuddySlotBtnDeny" image="{{{C_ImgBase}}}buddy-buddy-deny.dds" imagefocus="{{{C_ImgBase}}}buddy-buddy-deny-focus.dds"/>
  2017. <style id="Quad_BuddySlotBtnKick" image="{{{C_ImgBase}}}buddy-delete-off.dds" imagefocus="{{{C_ImgBase}}}buddy-delete-focus.dds"/>
  2018. <style id="Quad_MessageSlotBtnCopy" image="{{{C_ImgBase}}}buddy-copy-serverlink.dds" imagefocus="{{{C_ImgBase}}}buddy-copy-serverlink-on.dds"/>
  2019. <style id="Quad_InvitePlayerButton" image="{{{C_ImgBase}}}buddy-buddy-add.dds" imagefocus="{{{C_ImgBase}}}buddy--buddy-add-focus.dds"/>
  2020.  
  2021. <style id="Label_MessengerBuddyName" style="TextValueSmallSm" textsize="2" textemboss="1" textcolor="FFF"/>
  2022. <style id="Quad_MessengerBuddyRemove" image="{{{C_ImgBase}}}buddy-delete-off.dds" imagefocus="{{{C_ImgBase}}}buddy-delete-focus.dds"/>
  2023. <style id="Quad_MessengerBuddyJoin" image="{{{C_ImgBase}}}buddy-join.dds" imagefocus="{{{C_ImgBase}}}buddy-join-on.dds"/>
  2024.  
  2025. <style class="Check" sizen="4 4" valign="center" style="Icons64x64_1" substyle="Check"/>
  2026. </stylesheet>
  2027.  
  2028. <frame id="Frame_Cursor">
  2029. <label halign="center" valign="center2" text="+" textcolor="FFF" textemboss="1"/>
  2030. <label posn="0 -3" halign="center" valign="center2" textcolor="FFF" textemboss="1" textsize="1" id="Label_Cursor"/>
  2031. </frame>
  2032.  
  2033. <!-- Model of the mode change buttons -->
  2034. <framemodel id="FrameModel_ModeButton">
  2035. <quad sizen="6 6" halign="center" valign="center" colorize="FFF" class="ModeButton focus-2 valid-0" id="Quad_ModeButtonIcon" ScriptEvents="1"/>
  2036. <frame id="Frame_ModeButtonNotice" posn="1.5 1.5 1" hidden="1">
  2037. <quad sizen="2.5 2.5" halign="center" valign="center" image="file://Media/Manialinks/Common/disc.dds" colorize="B00"/>
  2038. <label posn="0 0 1" halign="center" valign="center2" style="TextValueSmallSm" scale=".45" textcolor="FFF" id="Label_ModeButtonNotice"/>
  2039. </frame>
  2040. </framemodel>
  2041.  
  2042. <!-- Model of the buddies list slots -->
  2043. <framemodel id="FrameModel_BuddySlot">
  2044. <quad posn="0 -.25" sizen="44 7.5" bgcolor="000" opacity=".125" class="valid-1" id="Quad_BuddySlotBgCard" ScriptEvents="1"/>
  2045. <quad posn="0 -.25 .1" sizen="44 7.5" bgcolor="0AF" opacity="0" id="Quad_BuddySlotBlink"/>
  2046. <label posn="43.5 -7.5 .2" halign="right" valign="bottom" scale=".5" textemboss="0" textcolor="0AF" id="Label_BuddySlotNbNotice"/>
  2047.  
  2048. <!-- Presence lights -->
  2049. <quad posn="0 -.25 1" sizen="1 7.5" opacity=".6" id="Quad_BuddySlotPresence"/>
  2050. <quad posn="-2.3 2 .9" sizen="5.5 12" style="Bgs1InRace" substyle="BgButtonGlow" id="Quad_BuddySlotGlow" hidden="1"/>
  2051.  
  2052. <!-- Name and status -->
  2053. <label posn="2 -2.5 1" sizen="33.5 3" valign="center2" textsize="1" textcolor="FFF" id="Label_BuddySlotName"/>
  2054. <label posn="2 -5.75 1" sizen="48.5 3" scale=".75" valign="center2" textsize="1" textcolor="FFF" id="Label_BuddySlotStatus"/>
  2055.  
  2056. <!-- Control buttons -->
  2057. <quad posn="41.5 -4 1" sizen="3.5 3.5" halign="center" valign="center" class="focus-1 valid-1" id="Quad_BuddySlotBtnJoin" ScriptEvents="1" hidden="1"/>
  2058. <quad posn="38.0 -4 1" sizen="3.5 3.5" halign="center" valign="center" class="focus-1 valid-1" id="Quad_BuddySlotBtnAdd" ScriptEvents="1" hidden="1"/>
  2059. <quad posn="41.5 -4 1" sizen="3.5 3.5" halign="center" valign="center" class="focus-1 valid-1" id="Quad_BuddySlotBtnDeny" ScriptEvents="1" hidden="1"/>
  2060. <quad posn="41.5 -4 1" sizen="3.5 3.5" halign="center" valign="center" class="focus-1 valid-1" id="Quad_BuddySlotBtnKick" ScriptEvents="1" hidden="1"/>
  2061. <quad posn="38.0 -4 1" sizen="3.5 3.5" halign="center" valign="center" class="focus-1 valid-1" id="Quad_BuddySlotBtnMute" ScriptEvents="1" hidden="1"/>
  2062. </framemodel>
  2063.  
  2064. <!-- Model of the the messages items -->
  2065. <framemodel id="FrameModel_MessageSlot">
  2066. <quad posn="0 -.25" sizen="124 7.5" bgcolor="000" opacity=".25" id="Quad_MessageSlotBgCard"/>
  2067. <quad posn="1 -2.5 1" sizen="2.25 2.25" valign="center" class="focus1 valid1" id="Quad_MessageSlotBtnCopy" ScriptEvents="1"/>
  2068. <label posn="4 -2.5 1" sizen="80 4" valign="center2" scale=".9" textsize="1" textcolor="FFF" text="Buddy name" id="Label_MessageSlotName"/>
  2069. <label posn="123 -2.5 1" halign="right" valign="center2" scale=".9" textsize="1" textcolor="FFF" opacity=".375" id="Label_MessageSlotTime"/>
  2070. <label posn="1 -4.25 1" sizen="122" textsize="1" textemboss="1" textcolor="FFF" autonewline="1" text="Message body" id="Label_MessageSlotBody"/>
  2071. </framemodel>
  2072.  
  2073. <!-- Frame preventing going off screen while using VR devices -->
  2074. <frame clip="1" clipsizen="320 180">
  2075.  
  2076. <!-- Plugin window itself -->
  2077. <frame id="Frame_EvidencePlugin" posn="0 204">
  2078. <!-- Buddies list window -->
  2079. <frame id="Frame_BuddiesList" posn="-24">
  2080. <!-- Background images -->
  2081. <quad sizen="48.5 106" image="file://Media/Manialinks/Common/background2.png" ScriptEvents="1"/>
  2082. <quad posn="0 0 -1" sizen="48 104" style="Bgs1" substyle="BgDialogBlur" opacity="0"/>
  2083. <quad posn="-3 3 1" sizen="54 7.5" style="Bgs1InRace" substyle="BgGlow2"/>
  2084. <quad posn="0 -104.5 1" sizen="48 1" style="Bgs1InRace" substyle="BgMetalBar"/>
  2085.  
  2086. <!-- Mode buttons -->
  2087. <frame id="Frame_ModeButtons" posn="4.5 -7.75 1">
  2088. <frameinstance posn="0" modelid="FrameModel_ModeButton" id="Frame_ModeButtonBuddies"/>
  2089. <frameinstance posn="6" modelid="FrameModel_ModeButton" id="Frame_ModeButtonGroup"/>
  2090. <frameinstance posn="12" modelid="FrameModel_ModeButton" id="Frame_ModeButtonRequests"/>
  2091. <!-- <frameinstance posn="18" modelid="FrameModel_ModeButton" id="Frame_ModeButtonGlobal"/> -->
  2092. <frameinstance posn="33" modelid="FrameModel_ModeButton" id="Frame_ModeButtonMailbox"/>
  2093. <frameinstance posn="39" modelid="FrameModel_ModeButton" id="Frame_ModeButtonSettings"/>
  2094. </frame>
  2095.  
  2096. <!-- User own Slot -->
  2097. <frameinstance posn="2 -10.75 1" modelid="FrameModel_BuddySlot" id="Frame_LocalUserSlot"/>
  2098.  
  2099. <!-- Buddies Slots -->
  2100. <frame id="Frame_BuddiesSlots" posn="2 -18.75 1">
  2101. <frameinstance posn="0 0" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#0"/>
  2102. <frameinstance posn="0 -8" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#1"/>
  2103. <frameinstance posn="0 -16" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#2"/>
  2104. <frameinstance posn="0 -24" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#3"/>
  2105. <frameinstance posn="0 -32" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#4"/>
  2106. <frameinstance posn="0 -40" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#5"/>
  2107. <frameinstance posn="0 -48" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#6"/>
  2108. <frameinstance posn="0 -56" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#7"/>
  2109. <frameinstance posn="0 -64" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#8"/>
  2110. <frameinstance posn="0 -72" modelid="FrameModel_BuddySlot" id="Frame_BuddySlot#9"/>
  2111. </frame>
  2112.  
  2113. <!-- Buddy inviting -->
  2114. <frame posn="2 -10.75 1" id="Frame_BuddyInviteCard" hidden="1">
  2115. <quad posn="0 -.25" sizen="44 7.5" bgcolor="000" opacity=".125"/>
  2116. <label posn="1 -2.25 1" sizen="48.5 3" scale=".75" valign="center2" textsize="1" textcolor="FFF" text="Add player to buddies list:"/>
  2117. <entry posn="1 -5.5 1" sizen="38 3.5" valign="center2" textsize="1" textcolor="FFF" id="Entry_InvitePlayerInput" ScriptEvents="1"/>
  2118. <quad posn="41.5 -4 1" sizen="3.5 3.5" halign="center" valign="center" class="focus-1 valid-1" id="Quad_InvitePlayerButton" ScriptEvents="1" hidden="1"/>
  2119. </frame>
  2120.  
  2121. <!-- Page switch -->
  2122. <frame id="Frame_PageSwitch" posn="24 -101.5 1">
  2123. <quad posn="-8 0 1" sizen="5 5" halign="center" valign="center" style="Icons64x64_1" substyle="ArrowPrev" id="Quad_PrevBuddiesPage" ScriptEvents="1"/>
  2124. <label halign="center" valign="center2" style="TextValueSmallSm" textsize="1" id="Label_PageSwitchCounter"/>
  2125. <quad posn="8 0 1" sizen="5 5" halign="center" valign="center" style="Icons64x64_1" substyle="ArrowNext" id="Quad_NextBuddiesPage" ScriptEvents="1"/>
  2126. <quad posn="-8" sizen="5 5" halign="center" valign="center" style="Icons64x64_1" substyle="ArrowDisabled"/>
  2127. <quad posn="8" sizen="5 5" halign="center" valign="center" style="Icons64x64_1" substyle="ArrowDisabled"/>
  2128. </frame>
  2129.  
  2130. <!-- Settings tab -->
  2131. <frame id="Frame_SettingsMenu" posn="2 -14 1" hidden="1">
  2132. <label posn="0 0" valign="center2" style="TextButtonNav" textsize="1" textcolor="FFF" text="Settings" translate="1"/>
  2133.  
  2134. <label posn="0 -5" valign="center2" textsize="1" textcolor="FFF" text="Status with current activity"/>
  2135. <quad posn="40.5 -5" class="Check" id="Quad_CheckUseDynamicStatus" ScriptEvents="1"/>
  2136.  
  2137. <label posn="0 -10" valign="center2" textsize="1" textcolor="FFF" text="Automatically format links"/>
  2138. <quad posn="40.5 -10" class="Check" id="Quad_CheckUseLinksPhrasing" ScriptEvents="1"/>
  2139.  
  2140. <label posn="0 -15" valign="center2" textsize="1" textcolor="FFF" text="Group password"/>
  2141. <entry posn="44 -15" sizen="16 3.5" halign="right" valign="center2" textsize="1" textemboss="1" textcolor="FFF" textformat="newpassword" id="Entry_GroupChatPassword" ScriptEvents="1"/>
  2142.  
  2143. <label posn="0 -20" valign="center2" textsize="1" textcolor="FFF" text="Enable Global Chat"/>
  2144. <quad posn="40.5 -20" class="Check" id="Quad_CheckEnableGlobalChat" ScriptEvents="1"/>
  2145.  
  2146. <label posn="0 -25" valign="center2" textsize="1" textcolor="FFF" text="Notice on new message"/>
  2147. <quad posn="40.5 -25" class="Check" id="Quad_CheckNoticeOnNewMessage" ScriptEvents="1"/>
  2148.  
  2149. <label posn="0 -30" valign="center2" textsize="1" textcolor="FFF" text="Notice on new connection"/>
  2150. <quad posn="40.5 -30" class="Check" id="Quad_CheckNoticeOnConnection" ScriptEvents="1"/>
  2151. </frame>
  2152.  
  2153. <label
  2154. posn="24 -75.5 1" halign="center" style="CardButtonMediumL" text="Download update" id="Label_ButtonUpdate" hidden="1"
  2155. url="https://raw.githubusercontent.com/domino54/title-packs/master/Plugins/Evidence.Script.txt"
  2156. />
  2157.  
  2158. <textedit posn="2 -84.5 1" sizen="44 18" textsize="1" textcolor="FFF" id="TextEdit_PasteBin"/>
  2159. </frame>
  2160.  
  2161. <!-- Messaging window -->
  2162. <frame id="Frame_MessengerWindow" posn="164">
  2163. <!-- Background images -->
  2164. <quad posn="-.25" sizen="137 106" image="file://Media/Manialinks/Common/background3.png" ScriptEvents="1"/>
  2165. <quad posn="0 0 -1" sizen="137 104" style="Bgs1" substyle="BgDialogBlur" opacity="0"/>
  2166. <quad posn="-3 3 1" sizen="142 7.5" style="Bgs1InRace" substyle="BgGlow2"/>
  2167. <quad posn="0 -104.5 1" sizen="136 1" style="Bgs1InRace" substyle="BgMetalBar"/>
  2168.  
  2169. <!-- User information -->
  2170. <frame id="Frame_MessengerBuddyInfo" posn="2 .25 1">
  2171. <label posn="0 -4.5 1" sizen="60 4" valign="center2" id="Label_MessengerBuddyName"/>
  2172. <quad posn="-.9 -8.5 1" sizen="4.5 4.5" valign="center" style="Icons64x64_1" substyle="ClipPause" id="Quad_MessengerBuddyPresence" ScriptEvents="1"/>
  2173. <label posn="4 -8.5 1" sizen="60 3" valign="center2" textsize="1" textemboss="1" textcolor="FC0" id="Label_MessengerBuddyStatus"/>
  2174. <entry posn="4 -8.5 1" sizen="60 3.5" valign="center2" textsize="1" textemboss="1" textcolor="FC0" id="Entry_MessengerStatusInput" ScriptEvents="1" hidden="1"/>
  2175. </frame>
  2176.  
  2177. <!-- User actions -->
  2178. <frame id="Frame_MessengerBuddyActions" posn="134.5 -6.1 1">
  2179. <!-- Server name and join button -->
  2180. <quad posn="-6 0 1" sizen="6 6" valign="center" class="focus-1 valid-1" id="Quad_MessengerBuddyJoin" ScriptEvents="1" hidden="1"/>
  2181. <quad posn="-6" sizen="6 6" valign="center" image="{{{C_ImgBase}}}buddy-join-off.dds"/>
  2182. <label posn="-6.5 1.75" sizen="60 3" halign="right" valign="center2" textsize="1" textcolor="FFF" textemboss="1" id="Label_MessengerBuddyServer"/>
  2183.  
  2184. <!-- Action buttons -->
  2185. <quad posn="-15 -1.75" sizen="4 4" valign="center" class="focus-1 valid-1" id="Quad_MessengerBuddyRemove" ScriptEvents="1"/>
  2186. <quad posn="-10.5 -1.75" sizen="4 4" valign="center" style="Icons64x64_1" substyle="Outbox" id="Quad_MessengerBuddyMail" ScriptEvents="1"/>
  2187.  
  2188. <!-- Buddy login -->
  2189. <label posn="-15.5 -1.75" sizen="30 3" halign="right" valign="center2" textsize="1" textemboss="1" textcolor="AAA" id="Label_MessengerBuddyLogin"/>
  2190. </frame>
  2191.  
  2192. <!-- Messages models -->
  2193. <frame id="Frame_MessagesSlots" posn="2 -98.75 1" clip="1" clipposn="66 42.75" clipsizen="132 87.5">
  2194. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#0" hidden="1"/>
  2195. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#1" hidden="1"/>
  2196. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#2" hidden="1"/>
  2197. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#3" hidden="1"/>
  2198. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#4" hidden="1"/>
  2199. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#5" hidden="1"/>
  2200. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#6" hidden="1"/>
  2201. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#7" hidden="1"/>
  2202. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#8" hidden="1"/>
  2203. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#9" hidden="1"/>
  2204. <frameinstance modelid="FrameModel_MessageSlot" id="Frame_MessageSlot#10" hidden="1"/>
  2205. </frame>
  2206.  
  2207. <frame id="Frame_BottomControls" posn="0 -101.5 1">
  2208. <!-- Message entry -->
  2209. <entry posn="2" sizen="122 4" valign="center2" textsize="1" textcolor="FFF" id="Entry_MessageSubmit" ScriptEvents="1"/>
  2210.  
  2211. <!-- Control buttons -->
  2212. <quad posn="125 0 1" sizen="5 5" valign="center" style="Icons64x64_1" substyle="ArrowUp" id="Quad_MessagesScrollUp" ScriptEvents="1" hidden="1"/>
  2213. <quad posn="130 0 1" sizen="5 5" valign="center" style="Icons64x64_1" substyle="ArrowDown" id="Quad_MessagesScrollDown" ScriptEvents="1" hidden="1"/>
  2214. <quad posn="125" sizen="5 5" valign="center" style="Icons64x64_1" substyle="ArrowDisabled"/>
  2215. <quad posn="130" sizen="5 5" valign="center" style="Icons64x64_1" substyle="ArrowDisabled"/>
  2216. </frame>
  2217. </frame>
  2218. </frame>
  2219. </frame>
  2220. <script><!--
  2221. /**
  2222. * EVIDENCE by domino54
  2223. * Interface manialink
  2224. */
  2225.  
  2226. #Include "AnimLib" as AL
  2227. #Include "MathLib" as ML
  2228. #Include "TextLib" as TL
  2229.  
  2230. #Const C_WidgetAnimDuration 200. ///< Duration of the show/hide animations
  2231. #Const C_EvidenceFramePosY 84. ///< Position of the Evidence window when visible
  2232. #Const C_EvidenceFramePosHide 120. ///< Position offset when Evidence window is hidden
  2233. #Const C_MessengerFramePosX 24. ///< Position of the Messenger window when visible
  2234. #Const C_MessengerFramePosHide 140. ///< Position offset when Messenger window is hidden
  2235. #Const C_MaxMessagesInHistory 48 ///< Maximum amount of messages stored per conversation
  2236.  
  2237. /// Update checker
  2238. #Const C_UpdateCheckInterval 1800000
  2239. #Const C_UpdateCheckAddress "https://raw.githubusercontent.com/domino54/title-packs/master/evidence-version.txt"
  2240.  
  2241. /// Available modes in the Evidence widget (with exception of Mailbox)
  2242. #Const C_ChatWidgetModes ["Buddies", "Group", "Requests", /* "Global", */ "Mailbox", "Settings"]
  2243.  
  2244. /// Default statuses for users presences
  2245. #Const C_UserPresenceStatus [_("Offline"), _("Available"), _("Away"), _("Busy"), _("Wanna talk!"), _("Snooze")]
  2246.  
  2247. /// Global Chat connection status
  2248. #Const C_GlobalChatConnectionStatus [0 => _("Offline"), 1 => _("Connected"), 3 => _("|Broadcasting|Connecting...")]
  2249.  
  2250. /// Colors of the users presences
  2251. #Const C_UserPresenceColors [
  2252. <.2, .4, .5>, ///< Offline
  2253. <.3, 1., .3>, ///< Available
  2254. <1., 1., 0.>, ///< Away
  2255. <1., .3, .3>, ///< Busy
  2256. <0., .7, 1.>, ///< Wanna talk!
  2257. <1., .8, 0.> ///< Snooze
  2258. ]
  2259.  
  2260. /// Opacity of the mode buttons
  2261. #Const C_ModeButtonsOpacity [
  2262. False => [ ///< Disabled
  2263. False => .25, ///< Off
  2264. True => .625 ///< Focus
  2265. ],
  2266. True => [ ///< Selected
  2267. False => .875, ///< Off
  2268. True => 1. ///< Focus
  2269. ]
  2270. ]
  2271.  
  2272. /// Colors of the buddies cards
  2273. #Const C_BuddySlotBgColors [
  2274. False => [ ///< Disabled
  2275. False => <0., 0., 0.>, ///< Off
  2276. True => <.3, .3, .3> ///< Focus
  2277. ],
  2278. True => [ ///< Selected
  2279. False => <.6, .6, .6>, ///< Off
  2280. True => <.9, .9, .9> ///< Focus
  2281. ]
  2282. ]
  2283.  
  2284. /// Mute button images
  2285. #Const C_SlotMuteButtonImages [
  2286. False => [ ///< Not muted
  2287. False => "{{{C_ImgBase}}}buddy-ally-on.dds",
  2288. True => "{{{C_ImgBase}}}buddy-ally-on-focus.dds"
  2289. ],
  2290. True => [ ///< Muted
  2291. False => "{{{C_ImgBase}}}buddy-ally-off.dds",
  2292. True => "{{{C_ImgBase}}}buddy-ally-focus.dds"
  2293. ]
  2294. ]
  2295.  
  2296. /// URLs of the mode buttons images
  2297. #Const C_ModeButtonsImagesURLs [
  2298. "Buddies" => "http://i.imgur.com/zWESBiR.png",
  2299. "Group" => "http://i.imgur.com/qFKByDl.png",
  2300. "Requests" => "http://i.imgur.com/TIAbhB7.png",
  2301. "Global" => "http://i.imgur.com/MXfIHAs.png",
  2302. "Mailbox" => "http://i.imgur.com/ULIzuFa.png",
  2303. "Settings" => "http://i.imgur.com/6ydip4k.png"
  2304. ]
  2305.  
  2306. // ---------------------------------- //
  2307. // Main
  2308. // ---------------------------------- //
  2309. ***Main***
  2310. ***
  2311. // ---------------------------------- //
  2312. // Load interface elements
  2313. declare Frame_EvidencePlugin <=> (Page.GetFirstChild("Frame_EvidencePlugin") as CMlFrame);
  2314. declare Frame_MessengerWindow <=> (Page.GetFirstChild("Frame_MessengerWindow") as CMlFrame);
  2315.  
  2316. /// Local user Slot
  2317. declare Frame_LocalUserSlot <=> (Page.GetFirstChild("Frame_LocalUserSlot") as CMlFrame);
  2318. declare Quad_LocalUserBgCard <=> (Frame_LocalUserSlot.GetFirstChild("Quad_BuddySlotBgCard") as CMlQuad);
  2319. declare Label_LocalUserBgName <=> (Frame_LocalUserSlot.GetFirstChild("Label_BuddySlotName") as CMlLabel);
  2320. declare Label_LocalUserStatus <=> (Frame_LocalUserSlot.GetFirstChild("Label_BuddySlotStatus") as CMlLabel);
  2321. declare Quad_LocalUserPresence <=> (Frame_LocalUserSlot.GetFirstChild("Quad_BuddySlotPresence") as CMlQuad);
  2322. declare Quad_LocalUserGlow <=> (Frame_LocalUserSlot.GetFirstChild("Quad_BuddySlotGlow") as CMlQuad);
  2323.  
  2324. /// Player inviting
  2325. declare Frame_BuddyInviteCard <=> (Page.GetFirstChild("Frame_BuddyInviteCard") as CMlFrame);
  2326. declare Entry_InvitePlayerInput <=> (Page.GetFirstChild("Entry_InvitePlayerInput") as CMlEntry);
  2327. declare Quad_InvitePlayerButton <=> (Page.GetFirstChild("Quad_InvitePlayerButton") as CMlQuad);
  2328.  
  2329. /// Buddies list page switch
  2330. declare Frame_PageSwitch <=> (Page.GetFirstChild("Frame_PageSwitch") as CMlFrame);
  2331. declare Quad_PrevBuddiesPage <=> (Page.GetFirstChild("Quad_PrevBuddiesPage") as CMlQuad);
  2332. declare Quad_NextBuddiesPage <=> (Page.GetFirstChild("Quad_NextBuddiesPage") as CMlQuad);
  2333. declare Label_PageSwitchCounter <=> (Page.GetFirstChild("Label_PageSwitchCounter") as CMlLabel);
  2334.  
  2335. /// Messenger scrolling
  2336. declare Quad_MessagesScrollUp <=> (Page.GetFirstChild("Quad_MessagesScrollUp") as CMlQuad);
  2337. declare Quad_MessagesScrollDown <=> (Page.GetFirstChild("Quad_MessagesScrollDown") as CMlQuad);
  2338.  
  2339. /// Messanger buddy information
  2340. declare Label_MessengerBuddyName <=> (Page.GetFirstChild("Label_MessengerBuddyName") as CMlLabel);
  2341. declare Quad_MessengerBuddyPresence <=> (Page.GetFirstChild("Quad_MessengerBuddyPresence") as CMlQuad);
  2342. declare Label_MessengerBuddyStatus <=> (Page.GetFirstChild("Label_MessengerBuddyStatus") as CMlLabel);
  2343. declare Entry_MessengerStatusInput <=> (Page.GetFirstChild("Entry_MessengerStatusInput") as CMlEntry);
  2344.  
  2345. /// Messenger buddy actions
  2346. declare Frame_MessengerBuddyActions <=> (Page.GetFirstChild("Frame_MessengerBuddyActions") as CMlFrame);
  2347. declare Label_MessengerBuddyLogin <=> (Page.GetFirstChild("Label_MessengerBuddyLogin") as CMlLabel);
  2348. declare Label_MessengerBuddyServer <=> (Page.GetFirstChild("Label_MessengerBuddyServer") as CMlLabel);
  2349. declare Quad_MessengerBuddyJoin <=> (Page.GetFirstChild("Quad_MessengerBuddyJoin") as CMlQuad);
  2350. declare Quad_MessengerBuddyMail <=> (Page.GetFirstChild("Quad_MessengerBuddyMail") as CMlQuad);
  2351. declare Quad_MessengerBuddyRemove <=> (Page.GetFirstChild("Quad_MessengerBuddyRemove") as CMlQuad);
  2352.  
  2353. /// Settings tab
  2354. declare Frame_SettingsMenu <=> (Page.GetFirstChild("Frame_SettingsMenu") as CMlFrame);
  2355. declare Quad_CheckUseDynamicStatus <=> (Page.GetFirstChild("Quad_CheckUseDynamicStatus") as CMlQuad);
  2356. declare Quad_CheckUseLinksPhrasing <=> (Page.GetFirstChild("Quad_CheckUseLinksPhrasing") as CMlQuad);
  2357. declare Quad_CheckEnableGroupChat <=> (Page.GetFirstChild("Quad_CheckEnableGroupChat") as CMlQuad);
  2358. declare Entry_GroupChatPassword <=> (Page.GetFirstChild("Entry_GroupChatPassword") as CMlEntry);
  2359. declare Quad_CheckEnableGlobalChat <=> (Page.GetFirstChild("Quad_CheckEnableGlobalChat") as CMlQuad);
  2360. declare Quad_CheckNoticeOnNewMessage <=> (Page.GetFirstChild("Quad_CheckNoticeOnNewMessage") as CMlQuad);
  2361. declare Quad_CheckNoticeOnConnection <=> (Page.GetFirstChild("Quad_CheckNoticeOnConnection") as CMlQuad);
  2362. declare Label_ButtonUpdate <=> (Page.GetFirstChild("Label_ButtonUpdate") as CMlLabel);
  2363. declare TextEdit_PasteBin <=> (Page.GetFirstChild("TextEdit_PasteBin") as CMlTextEdit);
  2364.  
  2365. /// Mode buttons
  2366. declare CMlFrame[Text] Frame_ModeButtons;
  2367. foreach (Mode in C_ChatWidgetModes) {
  2368. Frame_ModeButtons[Mode] <=> (Page.GetFirstChild("Frame_ModeButton"^Mode) as CMlFrame);
  2369. declare Quad_ModeButtonIcon <=> (Frame_ModeButtons[Mode].GetFirstChild("Quad_ModeButtonIcon") as CMlQuad);
  2370. Quad_ModeButtonIcon.ImageUrl = C_ModeButtonsImagesURLs[Mode];
  2371. Quad_ModeButtonIcon.DataAttributeSet("mode", Mode);
  2372. }
  2373.  
  2374. /// Buddies list slots
  2375. declare CMlFrame[] Frame_BuddiesSlots;
  2376. for (I, 0, 9) Frame_BuddiesSlots.add((Page.GetFirstChild("Frame_BuddySlot#"^I) as CMlFrame));
  2377.  
  2378. /// Messages slots
  2379. declare CMlFrame[] Frame_MessagesSlots;
  2380. for (I, 0, 10) Frame_MessagesSlots.add((Page.GetFirstChild("Frame_MessageSlot#"^I) as CMlFrame));
  2381.  
  2382. // ---------------------------------- //
  2383. // Persistent settings
  2384. declare persistent Text[][][Text] Persistent_Evidence_ChatHistory for Page;
  2385. declare persistent Integer[Text] Persistent_Evidence_NbUnreadMessages for Page;
  2386. declare persistent Integer Persistent_Evidence_UserTargetPresenceId for Page = 1;
  2387. declare persistent Text Persistent_Evidence_UserCustomStatus for Page;
  2388. declare persistent Text Persistent_Evidence_PasteBin for Page;
  2389.  
  2390. declare persistent Boolean Persistent_Evidence_UseDynamicStatus for Page = True;
  2391. declare persistent Boolean Persistent_Evidence_UseLinksPhrasing for Page = True;
  2392. declare persistent Text Persistent_Evidence_GroupChatPassword for Page;
  2393. declare persistent Boolean Persistent_Evidence_EnableGlobalChat for Page = True;
  2394. declare persistent Boolean Persistent_Evidence_NoticeOnNewMessage for Page = True;
  2395. declare persistent Boolean Persistent_Evidence_NoticeOnConnection for Page = True;
  2396.  
  2397. // ---------------------------------- //
  2398. // Plugin script communication
  2399. declare NewReceivedMessages for Page = Text[][]; ///< New messages to proceed
  2400. declare ChatWidgetIsOpen for Page = False; ///< Current chat state
  2401. declare MessengerIsOpen for Page = False; ///< Current messenger state
  2402. declare CurrentWidgetMode for Page = ""; ///< Active widget mode
  2403. declare SelectedConversation for Page = ""; ///< Login of selected buddy for private conversation
  2404. declare LegacyMailsAmount for Page = 0; ///< Amount of messages in classic mailbox
  2405. declare CurrentPluginPresenceId for Page = 1; ///< Current presence Id of the user
  2406. declare CurrentPluginStatusText for Page = ""; ///< Currently displayed status of the user
  2407. declare ManialinkTargetPresence for Page = 1; ///< Requested user presence Id
  2408. declare ManialinkCustomStatus for Page = ""; ///< Custom status specified by user
  2409. declare TotalNbUnreadMessages for Page = 0; ///< Total amount of unread messages
  2410. declare FlashTaskbar for Page = False; ///< Force game to blink taskbar icon
  2411.  
  2412. /// Settings
  2413. declare UseDynamicStatus for Page = False; ///< User context status setting
  2414. declare UseLinksPhrasing for Page = False; ///< User automatic link formatting setting
  2415. declare GroupChatPassword for Page = ""; ///< Group Chat password
  2416. declare EnableGlobalChat for Page = False; ///< Global Chat usage setting
  2417. declare NoticeOnNewMessage for Page = False; ///< Display notices on new messages
  2418. declare NoticeOnConnection for Page = False; ///< Display notice on buddy connection
  2419.  
  2420. declare GlobalChat_ConnectionStatus for Page = 0;
  2421.  
  2422. /// Update variables
  2423. declare PrevChatWidgetIsOpen = False;
  2424. declare PrevMessengerIsOpen = False;
  2425. declare PrevWidgetMode = "!";
  2426. declare PrevSelectedConversation = "!";
  2427. declare PrevLegacyMailsAmount = -1;
  2428. declare PrevPluginPresenceId = 0;
  2429. declare PrevEntryStatusValue = "!";
  2430. declare PrevGlobalChatConnectionStatus = -1;
  2431.  
  2432. // ---------------------------------- //
  2433. // Plugin buddies data
  2434. declare Text[] BuddiesList_Online for Page; ///< Buddies currently being connected
  2435. declare Text[] BuddiesList_Offline for Page; ///< Buddies currently being offline
  2436. declare Text[] BuddiesList_RequestFrom for Page; ///< Incoming buddies invitations
  2437. declare Text[] BuddiesList_RequestTo for Page; ///< Sent buddies invitations
  2438. declare Text[] BuddiesList_InGroup for Page; ///< Buddies in the group
  2439. declare Text[] BuddiesList_GlobalList for Page; ///< Buddies available on the global chat
  2440. declare Text[] BuddiesList_MutedUsers for Page; ///< Buddies available on the global chat
  2441.  
  2442. declare Text[] BuddiesList_ListOnTop for Page; ///< Buddies to be listed on top
  2443. declare Text[] BuddiesList_SortedList for Page; ///< Sorted list of all buddies (online and offline)
  2444. declare Text[] BuddiesList_RequestList for Page; ///< Sorted list of all requests
  2445.  
  2446. declare Text[Text] BuddiesName for Page; ///< Names of the buddies
  2447. declare Integer[Text] BuddiesPresenceId for Page; ///< Presence Ids of the buddies
  2448. declare Text[Text] BuddiesStatus for Page; ///< Statuses of the buddies
  2449. declare Text[Text] BuddiesServerLogin for Page; ///< Login of the servers buddies are on
  2450. declare Boolean[Text] BuddiesIsMuted for Page; ///< True if buddy is muted in Group Chat
  2451. declare Text[Text] BuddiesJoinLink for Page; ///< Links to join buddies servers
  2452.  
  2453. /// Global chat data
  2454. declare Integer[Text] GlobalChat_BuddiesPresenceId for Page;
  2455. declare Text[Text] GlobalChat_BuddiesName for Page;
  2456. declare Text[Text] GlobalChat_BuddiesStatus for Page;
  2457.  
  2458. declare Text[Text] ServersName for Page; ///< Names of the buddies servers
  2459.  
  2460. /// Update variables
  2461. declare PrevBuddiesOnline = -1;
  2462. declare PrevBuddiesOffline = -1;
  2463. declare PrevBuddiesRequestFrom = -1;
  2464. declare PrevBuddiesRequestTo = -1;
  2465. declare PrevBuddiesInGroup = -1;
  2466. declare PrevBuddiesGlobalList = -1;
  2467. declare PrevBuddiesMutedUsers = -1;
  2468.  
  2469. declare Text[Text] PrevBuddiesName;
  2470. declare Integer[Text] PrevBuddiesPresenceId;
  2471. declare Text[Text] PrevBuddiesStatus;
  2472. declare Text[Text] PrevBuddiesServerLogin;
  2473. declare Text[Text] PrevGlobalBuddiesName;
  2474. declare Integer[Text] PrevGlobalBuddiesPresenceId;
  2475.  
  2476. // ---------------------------------- //
  2477. // Variables
  2478. declare SortBuddiesList = True; ///< Forces manialink to sort Buddies tab
  2479. declare SortRequestsList = True; ///< Forces manialink to sort Requests tab
  2480. declare UpdateBuddiesList = True; ///< Forces manialink to build buddies list
  2481. declare HighlightModeButton = ""; ///< ID of the mode button to highlight
  2482. declare UpdateModeButtons = True; ///< Update opacity of the mode buttons
  2483. declare HighlightBuddySlot = NullId; ///< ID of the buddy slot to highlight
  2484. declare UpdateSlotsBgSlots = True; ///< Update backgrounds of the buddies slots
  2485. declare UpdateMessagesSlots = 2; ///< Amount of pending messages slots updates
  2486. declare UpdateMessengerInfo = True; ///< Update name and status of the conversation
  2487. declare MessagesOffset = Integer[Text]; ///< Messages scrolling option
  2488. declare NextUpdateCheckout = 0; ///< Time of the next update check
  2489. declare PluginIsOutdated = False;
  2490. declare UpdateCheckRequest = CHttpRequest;
  2491.  
  2492. /// Animations
  2493. declare AnimStartTime_Evidence = 0;
  2494. declare AnimStartTime_Messenger = 0;
  2495.  
  2496. /// Current and total page number on tabs
  2497. declare Integer[Text] CurrentPage;
  2498. declare Integer[Text] PagesCount;
  2499. foreach (Mode in C_ChatWidgetModes) {
  2500. CurrentPage[Mode] = 1;
  2501. PagesCount[Mode] = 1;
  2502. }
  2503.  
  2504. /// Unread messages amount
  2505. declare UnreadMessagesGroups = ["Buddies", "Group", "Global"];
  2506. declare Integer[Text] NbUnreadMessages;
  2507. declare Integer[Text] PrevNbUnreadMessages;
  2508. foreach (Group in UnreadMessagesGroups) {
  2509. NbUnreadMessages[Group] = 0;
  2510. PrevNbUnreadMessages[Group] = 0;
  2511. }
  2512.  
  2513. // ---------------------------------- //
  2514. // Initialize variables
  2515. ManialinkTargetPresence = Persistent_Evidence_UserTargetPresenceId;
  2516. Entry_MessengerStatusInput.Value = Persistent_Evidence_UserCustomStatus;
  2517. Entry_GroupChatPassword.Value = Persistent_Evidence_GroupChatPassword;
  2518. TextEdit_PasteBin.Value = Persistent_Evidence_PasteBin;
  2519. Quad_LocalUserBgCard.DataAttributeSet("login", LocalUser.Login);
  2520. CurrentWidgetMode = "Buddies";
  2521. ***
  2522.  
  2523. // ---------------------------------- //
  2524. // Yield
  2525. // ---------------------------------- //
  2526. ***Yield***
  2527. ***
  2528. // ---------------------------------- //
  2529. // Manage events
  2530. foreach (Event in PendingEvents) {
  2531. // ---------------------------------- //
  2532. // Keyboard button press
  2533. if (Event.Type == CMlEvent::Type::KeyPress) {
  2534. // ---------------------------------- //
  2535. // Change Evidence visibility
  2536. if (Event.KeyName == "F7") ChatWidgetIsOpen = !ChatWidgetIsOpen;
  2537. }
  2538. // ---------------------------------- //
  2539. // Mouse click
  2540. else if (Event.Type == CMlEvent::Type::MouseClick) {
  2541. // ---------------------------------- //
  2542. // Change current widget mode
  2543. if (Event.ControlId == "Quad_ModeButtonIcon") {
  2544. declare NewMode = Event.Control.DataAttributeGet("mode");
  2545. if (NewMode == "Mailbox") OpenLink("#mailto=", ::LinkType::ManialinkBrowser);
  2546. else CurrentWidgetMode = NewMode;
  2547. }
  2548. // ---------------------------------- //
  2549. // Change current widget mode
  2550. else if (Event.ControlId == "Quad_BuddySlotBgCard") {
  2551. // Go to the Group mode
  2552. if (Event.Control == Quad_LocalUserBgCard) CurrentWidgetMode = "Group";
  2553.  
  2554. // Select buddy
  2555. else if (CurrentWidgetMode != "Global") {
  2556. declare BuddyLogin = Event.Control.DataAttributeGet("login");
  2557. if (SelectedConversation != BuddyLogin) {
  2558. SelectedConversation = BuddyLogin;
  2559. if (CurrentWidgetMode == "Group") CurrentWidgetMode = "Buddies";
  2560. UpdateMessagesSlots = 2;
  2561. }
  2562. else SelectedConversation = "";
  2563. }
  2564. UpdateSlotsBgSlots = True;
  2565. }
  2566. // ---------------------------------- //
  2567. // Buddies list previous page button
  2568. else if (Event.ControlId == "Quad_PrevBuddiesPage") {
  2569. if (CurrentPage[CurrentWidgetMode] > 1) CurrentPage[CurrentWidgetMode] -= 1;
  2570. UpdateBuddiesList = True;
  2571. }
  2572. // ---------------------------------- //
  2573. // Buddies list next page button
  2574. else if (Event.ControlId == "Quad_NextBuddiesPage") {
  2575. if (CurrentPage[CurrentWidgetMode] < PagesCount[CurrentWidgetMode]) CurrentPage[CurrentWidgetMode] += 1;
  2576. UpdateBuddiesList = True;
  2577. }
  2578. // ---------------------------------- //
  2579. // Scroll messages up
  2580. else if (Event.ControlId == "Quad_MessagesScrollUp") {
  2581. declare Text BuddyLogin;
  2582. switch (CurrentWidgetMode) {
  2583. case "Group" : BuddyLogin = "*group*";
  2584. case "Global" : BuddyLogin = "*global*";
  2585. default : BuddyLogin = SelectedConversation;
  2586. }
  2587. if (!MessagesOffset.existskey(BuddyLogin)) MessagesOffset[BuddyLogin] = 0;
  2588. MessagesOffset[BuddyLogin] += 1;
  2589. UpdateMessagesSlots = 2;
  2590. }
  2591. // ---------------------------------- //
  2592. // Scroll messages down
  2593. else if (Event.ControlId == "Quad_MessagesScrollDown") {
  2594. declare Text BuddyLogin;
  2595. switch (CurrentWidgetMode) {
  2596. case "Group" : BuddyLogin = "*group*";
  2597. case "Global" : BuddyLogin = "*global*";
  2598. default : BuddyLogin = SelectedConversation;
  2599. }
  2600. if (!MessagesOffset.existskey(BuddyLogin)) MessagesOffset[BuddyLogin] = 0;
  2601. MessagesOffset[BuddyLogin] -= 1;
  2602. UpdateMessagesSlots = 2;
  2603. }
  2604. // ---------------------------------- //
  2605. // Send buddy invitation
  2606. else if (Event.ControlId == "Quad_InvitePlayerButton") {
  2607. SendCustomEvent("AddBuddy", [Entry_InvitePlayerInput.Value]);
  2608. Entry_InvitePlayerInput.Value = "";
  2609. }
  2610. // ---------------------------------- //
  2611. // Accept buddy request
  2612. else if (Event.ControlId == "Quad_BuddySlotBtnAdd") {
  2613. declare Login = Event.Control.DataAttributeGet("login");
  2614. if (Login != "") SendCustomEvent("BuddyAccept", [Login]);
  2615. }
  2616. // ---------------------------------- //
  2617. // Deny / cancel buddy request
  2618. else if (Event.ControlId == "Quad_BuddySlotBtnDeny") {
  2619. declare Login = Event.Control.DataAttributeGet("login");
  2620. if (Login != "") SendCustomEvent("BuddyDeny", [Login]);
  2621. }
  2622. // ---------------------------------- //
  2623. // Cycle through available presences
  2624. else if (Event.ControlId == "Quad_MessengerBuddyPresence") {
  2625. if (CurrentWidgetMode == "Group") {
  2626. ManialinkTargetPresence += 1;
  2627. if (ManialinkTargetPresence > 5) ManialinkTargetPresence = 1;
  2628. Persistent_Evidence_UserTargetPresenceId = ManialinkTargetPresence;
  2629. }
  2630. }
  2631. // ---------------------------------- //
  2632. // Send mail to specified buddy
  2633. else if (Event.ControlId == "Quad_MessengerBuddyMail") {
  2634. declare BuddyLogin = Event.Control.DataAttributeGet("login");
  2635. if (BuddyLogin != "") OpenLink("#mailto="^BuddyLogin, ::LinkType::ManialinkBrowser);
  2636. }
  2637. // ---------------------------------- //
  2638. // Remove buddy
  2639. else if (Event.ControlId == "Quad_MessengerBuddyRemove") {
  2640. declare Login = Event.Control.DataAttributeGet("login");
  2641. if (Login != "") SendCustomEvent("RemoveBuddy", [Login]);
  2642. SelectedConversation = "";
  2643. }
  2644. // ---------------------------------- //
  2645. // Copy message content buttons
  2646. else if (Event.ControlId == "Quad_MessageSlotBtnCopy") {
  2647. declare ClipboardContents = Event.Control.DataAttributeGet("clipboard");
  2648. if (ClipboardContents != "") SendCustomEvent("SetClipboard", [ClipboardContents]);
  2649. }
  2650.  
  2651. // ---------------------------------- //
  2652. // Open manialink
  2653. if (Event.Control.DataAttributeExists("manialink")) {
  2654. declare ManialinkCode = Event.Control.DataAttributeGet("manialink");
  2655. if (ManialinkCode != "") {
  2656. OpenLink(ManialinkCode, ::LinkType::ManialinkBrowser);
  2657. ChatWidgetIsOpen = False;
  2658. }
  2659. }
  2660.  
  2661. // ---------------------------------- //
  2662. // Send command
  2663. if (Event.Control.DataAttributeExists("command")) {
  2664. declare Command = Event.Control.DataAttributeGet("command");
  2665. if (Command != "") SendCustomEvent("SendMessage", ["*group*", Command]);
  2666. }
  2667.  
  2668. // ---------------------------------- //
  2669. // Change Evidence settings
  2670. if (Event.Control.HasClass("Check")) {
  2671. switch (Event.ControlId) {
  2672. case "Quad_CheckUseDynamicStatus" : Persistent_Evidence_UseDynamicStatus = !Persistent_Evidence_UseDynamicStatus;
  2673. case "Quad_CheckUseLinksPhrasing" : Persistent_Evidence_UseLinksPhrasing = !Persistent_Evidence_UseLinksPhrasing;
  2674. case "Quad_CheckEnableGlobalChat" : Persistent_Evidence_EnableGlobalChat = !Persistent_Evidence_EnableGlobalChat;
  2675. case "Quad_CheckNoticeOnNewMessage" : Persistent_Evidence_NoticeOnNewMessage = !Persistent_Evidence_NoticeOnNewMessage;
  2676. case "Quad_CheckNoticeOnConnection" : Persistent_Evidence_NoticeOnConnection = !Persistent_Evidence_NoticeOnConnection;
  2677. }
  2678. }
  2679.  
  2680. // ---------------------------------- //
  2681. // Play sounds
  2682. if (Event.Control.HasClass("valid-0")) Audio.PlaySoundEvent(CAudioManager::ELibSound::Valid, 0, 0.);
  2683. if (Event.Control.HasClass("valid-1")) Audio.PlaySoundEvent(CAudioManager::ELibSound::Valid, 1, 0.);
  2684. }
  2685. // ---------------------------------- //
  2686. // Mouse hover
  2687. else if (Event.Type == CMlEvent::Type::MouseOver) {
  2688. // ---------------------------------- //
  2689. // Highlight mode buttons
  2690. if (Event.ControlId == "Quad_ModeButtonIcon") {
  2691. HighlightModeButton = Event.Control.DataAttributeGet("mode");
  2692. UpdateModeButtons = True;
  2693. }
  2694. // ---------------------------------- //
  2695. // Highlight buddy slot
  2696. else if (Event.ControlId == "Quad_BuddySlotBgCard") {
  2697. HighlightBuddySlot = Event.Control.Id;
  2698. UpdateSlotsBgSlots = True;
  2699. }
  2700.  
  2701. // ---------------------------------- //
  2702. // Play sounds
  2703. if (Event.Control.HasClass("focus-1")) Audio.PlaySoundEvent(CAudioManager::ELibSound::Focus, 1, 0.);
  2704. if (Event.Control.HasClass("focus-2")) Audio.PlaySoundEvent(CAudioManager::ELibSound::Focus, 2, 0.);
  2705. }
  2706. // ---------------------------------- //
  2707. // Mouse hover end
  2708. else if (Event.Type == CMlEvent::Type::MouseOut) {
  2709. // ---------------------------------- //
  2710. // Highlight mode buttons
  2711. if (Event.ControlId == "Quad_ModeButtonIcon") {
  2712. HighlightModeButton = "";
  2713. UpdateModeButtons = True;
  2714. }
  2715. // ---------------------------------- //
  2716. // Highlight buddy slot
  2717. else if (Event.ControlId == "Quad_BuddySlotBgCard") {
  2718. HighlightBuddySlot = NullId;
  2719. UpdateSlotsBgSlots = True;
  2720. }
  2721. }
  2722. // ---------------------------------- //
  2723. // Entry submission
  2724. else if (Event.Type == CMlEvent::Type::EntrySubmit) {
  2725. declare Entry <=> (Event.Control as CMlEntry);
  2726. // ---------------------------------- //
  2727. // Message input
  2728. if (Event.ControlId == "Entry_MessageSubmit") {
  2729. if (Entry.Value != "" && Entry.Value != "$") {
  2730. // ---------------------------------- //
  2731. // Select conversation
  2732. declare Text TargetConversation;
  2733. switch (CurrentWidgetMode) {
  2734. case "Group" : TargetConversation = "*group*";
  2735. case "Global" : TargetConversation = "*global*";
  2736. default : TargetConversation = SelectedConversation;
  2737. }
  2738.  
  2739. // Send message
  2740. if (TargetConversation != "") {
  2741. declare FormattedMessage = FormatMessage(Entry.Value);
  2742. SendCustomEvent("SendMessage", [TargetConversation, FormattedMessage]);
  2743. if (TargetConversation != "*global*" && TargetConversation != "*group*" && TL::SubString(Entry.Value, 0, 1) != "/")
  2744. NewReceivedMessages.add([TargetConversation, LocalUser.Login, FormattedMessage]);
  2745. Entry.Value = "";
  2746. }
  2747. }
  2748. Entry.StartEdition();
  2749. }
  2750. // ---------------------------------- //
  2751. // Send buddy invitation
  2752. else if (Event.ControlId == "Entry_InvitePlayerInput") {
  2753. SendCustomEvent("AddBuddy", [Entry.Value]);
  2754. Entry.Value = "";
  2755. }
  2756. }
  2757. }
  2758.  
  2759. // ---------------------------------- //
  2760. // New messages to display
  2761. while (NewReceivedMessages.count > 0) {
  2762. declare MessageData = NewReceivedMessages[0];
  2763. declare Removed = NewReceivedMessages.removekey(0);
  2764.  
  2765. // ---------------------------------- //
  2766. // Get new message data
  2767. if (MessageData.count >= 3) {
  2768. declare ConversationLogin = MessageData[0];
  2769. declare SenderLogin = MessageData[1];
  2770. declare MessageBody = FormatMessage(MessageData[2]);
  2771.  
  2772. // Initialize conversation history array if empty
  2773. if (!Persistent_Evidence_ChatHistory.existskey(ConversationLogin))
  2774. Persistent_Evidence_ChatHistory[ConversationLogin] = Text[][];
  2775.  
  2776. // ---------------------------------- //
  2777. // Attach message to previous one if sender is the same
  2778. declare PreviousMessageId = Persistent_Evidence_ChatHistory[ConversationLogin].count - 1;
  2779. if (
  2780. Persistent_Evidence_ChatHistory[ConversationLogin].existskey(PreviousMessageId) &&
  2781. Persistent_Evidence_ChatHistory[ConversationLogin][PreviousMessageId][0] == SenderLogin
  2782. ) {
  2783. Persistent_Evidence_ChatHistory[ConversationLogin][PreviousMessageId][1] ^= "\n$z"^MessageBody;
  2784. Persistent_Evidence_ChatHistory[ConversationLogin][PreviousMessageId][2] = CurrentLocalDateText;
  2785. }
  2786.  
  2787. // ---------------------------------- //
  2788. // Save new message in history
  2789. else Persistent_Evidence_ChatHistory[ConversationLogin].add([
  2790. SenderLogin, MessageBody, CurrentLocalDateText
  2791. ]);
  2792.  
  2793. // ---------------------------------- //
  2794. // Remove oldest messages from history
  2795. declare SavedMessagesAmount = Persistent_Evidence_ChatHistory[ConversationLogin].count;
  2796. if (SavedMessagesAmount > C_MaxMessagesInHistory) for (I, 1, SavedMessagesAmount - C_MaxMessagesInHistory) {
  2797. declare Removed = Persistent_Evidence_ChatHistory[ConversationLogin].removekey(0);
  2798. }
  2799.  
  2800. // ---------------------------------- //
  2801. // Move buddy to the top of the list
  2802. if (!BuddiesList_ListOnTop.exists(ConversationLogin)) {
  2803. BuddiesList_ListOnTop.add(ConversationLogin);
  2804. SortBuddiesList = True;
  2805. }
  2806.  
  2807. // ---------------------------------- //
  2808. // Update messages slots manialink
  2809. declare SpecialMessageModes = ["Group" => "*group*", "Global" => "*global*"];
  2810. if (
  2811. (ConversationLogin == SelectedConversation && !SpecialMessageModes.exists(CurrentWidgetMode)) ||
  2812. (SpecialMessageModes.existskey(CurrentWidgetMode) && SpecialMessageModes[CurrentWidgetMode] == ConversationLogin)
  2813. )
  2814. UpdateMessagesSlots = 2;
  2815.  
  2816. // ---------------------------------- //
  2817. // Check if user should receive notification
  2818. declare NotifyUser = False;
  2819. switch (ConversationLogin) {
  2820. case "*group*" : NotifyUser = (CurrentWidgetMode != "Group");
  2821. case "*global*" : NotifyUser = (CurrentWidgetMode != "Global");
  2822. default : NotifyUser = (SelectedConversation != ConversationLogin || SpecialMessageModes.existskey(CurrentWidgetMode));
  2823. }
  2824.  
  2825. if (SenderLogin != LocalUser.Login && (NotifyUser || !ChatWidgetIsOpen)) {
  2826. // ---------------------------------- //
  2827. // Increase amount of unread messages
  2828. if (!Persistent_Evidence_NbUnreadMessages.existskey(ConversationLogin))
  2829. Persistent_Evidence_NbUnreadMessages[ConversationLogin] = 0;
  2830. Persistent_Evidence_NbUnreadMessages[ConversationLogin] += 1;
  2831.  
  2832. // ---------------------------------- //
  2833. // Play notification sound
  2834. if (CurrentPluginPresenceId != 3 && ConversationLogin != "*global*")
  2835. Audio.PlaySoundEvent(CAudioManager::ELibSound::Alert, 1, 0.);
  2836.  
  2837. // ---------------------------------- //
  2838. // Display notification
  2839. if (NoticeOnNewMessage) SendCustomEvent("ShowMessageNotice", [SenderLogin, MessageBody]);
  2840. }
  2841.  
  2842. // ---------------------------------- //
  2843. // Flash taskbar
  2844. if (SenderLogin != LocalUser.Login && ConversationLogin != "*global*")
  2845. FlashTaskbar = True;
  2846. }
  2847. }
  2848.  
  2849. // ---------------------------------- //
  2850. // Update unread messages amount
  2851. NbUnreadMessages["Buddies"] = 0;
  2852. foreach (Login => Amount in Persistent_Evidence_NbUnreadMessages) {
  2853. switch (Login) {
  2854. case "*group*" : NbUnreadMessages["Group"] = Amount;
  2855. case "*global*" : NbUnreadMessages["Global"] = Amount;
  2856. default : NbUnreadMessages["Buddies"] += Amount;
  2857. }
  2858. }
  2859.  
  2860. // ---------------------------------- //
  2861. // Set mode buttons notifications amount
  2862. foreach (Group in UnreadMessagesGroups) {
  2863. if (PrevNbUnreadMessages[Group] != NbUnreadMessages[Group]) {
  2864. PrevNbUnreadMessages[Group] = NbUnreadMessages[Group];
  2865. SetModeNotificationsCount(Group, NbUnreadMessages[Group]);
  2866. TotalNbUnreadMessages = NbUnreadMessages["Buddies"] + NbUnreadMessages["Group"];
  2867. }
  2868. }
  2869.  
  2870. // ---------------------------------- //
  2871. // Animations
  2872. // ---------------------------------- //
  2873.  
  2874. // ---------------------------------- //
  2875. // Trigger Evidence window animation
  2876. if (PrevChatWidgetIsOpen != ChatWidgetIsOpen) {
  2877. PrevChatWidgetIsOpen = ChatWidgetIsOpen;
  2878. AnimStartTime_Evidence = Now;
  2879. }
  2880.  
  2881. // ---------------------------------- //
  2882. // Perform Evidence window animation
  2883. if (Now < AnimStartTime_Evidence + C_WidgetAnimDuration) {
  2884. declare Anim_Easing = "EaseInCirc";
  2885. declare Anim_StartPos = C_EvidenceFramePosY;
  2886. declare Anim_Change = C_EvidenceFramePosHide;
  2887.  
  2888. if (ChatWidgetIsOpen) {
  2889. Anim_Easing = "EaseOutCirc";
  2890. Anim_StartPos += C_EvidenceFramePosHide;
  2891. Anim_Change *= -1;
  2892. }
  2893.  
  2894. Frame_EvidencePlugin.RelativePosition.Y = AL::Ease(
  2895. Anim_Easing,
  2896. ML::ToReal(Now - AnimStartTime_Evidence),
  2897. Anim_StartPos,
  2898. Anim_Change,
  2899. C_WidgetAnimDuration
  2900. );
  2901. } else {
  2902. Frame_EvidencePlugin.RelativePosition.Y = C_EvidenceFramePosY;
  2903. if (!ChatWidgetIsOpen) Frame_EvidencePlugin.RelativePosition.Y = C_EvidenceFramePosY + C_EvidenceFramePosHide;
  2904. }
  2905.  
  2906. // Set messenger window visibility
  2907. MessengerIsOpen = (CurrentWidgetMode == "Group" || CurrentWidgetMode == "Global" || SelectedConversation != "");
  2908.  
  2909. // ---------------------------------- //
  2910. // Trigger Messenger window animation
  2911. if (PrevMessengerIsOpen != MessengerIsOpen) {
  2912. PrevMessengerIsOpen = MessengerIsOpen;
  2913. AnimStartTime_Messenger = Now;
  2914. }
  2915.  
  2916. // ---------------------------------- //
  2917. // Perform Messenger window animation
  2918. if (Now < AnimStartTime_Messenger + C_WidgetAnimDuration) {
  2919. declare Anim_Easing = "EaseInCirc";
  2920. declare Anim_StartPos = C_MessengerFramePosX;
  2921. declare Anim_Change = C_MessengerFramePosHide;
  2922.  
  2923. if (MessengerIsOpen) {
  2924. Anim_Easing = "EaseOutCirc";
  2925. Anim_StartPos += C_MessengerFramePosHide;
  2926. Anim_Change *= -1;
  2927. }
  2928.  
  2929. Frame_MessengerWindow.RelativePosition.X = AL::Ease(
  2930. Anim_Easing,
  2931. ML::ToReal(Now - AnimStartTime_Messenger),
  2932. Anim_StartPos,
  2933. Anim_Change,
  2934. C_WidgetAnimDuration
  2935. );
  2936. } else {
  2937. Frame_MessengerWindow.RelativePosition.X = C_MessengerFramePosX;
  2938. if (!MessengerIsOpen) Frame_MessengerWindow.RelativePosition.X = C_MessengerFramePosX + C_MessengerFramePosHide;
  2939. }
  2940.  
  2941. // ---------------------------------- //
  2942. // Update settings
  2943. // ---------------------------------- //
  2944.  
  2945. // ---------------------------------- //
  2946. // Dynamic status
  2947. if (UseDynamicStatus != Persistent_Evidence_UseDynamicStatus) {
  2948. UseDynamicStatus = Persistent_Evidence_UseDynamicStatus;
  2949. Quad_CheckUseDynamicStatus.StyleSelected = UseDynamicStatus;
  2950. }
  2951.  
  2952. // ---------------------------------- //
  2953. // Links phrasing
  2954. if (UseLinksPhrasing != Persistent_Evidence_UseLinksPhrasing) {
  2955. UseLinksPhrasing = Persistent_Evidence_UseLinksPhrasing;
  2956. Quad_CheckUseLinksPhrasing.StyleSelected = UseLinksPhrasing;
  2957. }
  2958.  
  2959. // ---------------------------------- //
  2960. // Group Chat password
  2961. if (GroupChatPassword != Entry_GroupChatPassword.Value) {
  2962. GroupChatPassword = Entry_GroupChatPassword.Value;
  2963. Persistent_Evidence_GroupChatPassword = GroupChatPassword;
  2964. }
  2965.  
  2966. // ---------------------------------- //
  2967. // Global Chat
  2968. if (EnableGlobalChat != Persistent_Evidence_EnableGlobalChat) {
  2969. EnableGlobalChat = Persistent_Evidence_EnableGlobalChat;
  2970. Quad_CheckEnableGlobalChat.StyleSelected = EnableGlobalChat;
  2971. }
  2972.  
  2973. // ---------------------------------- //
  2974. // Notice on new message
  2975. if (NoticeOnNewMessage != Persistent_Evidence_NoticeOnNewMessage) {
  2976. NoticeOnNewMessage = Persistent_Evidence_NoticeOnNewMessage;
  2977. Quad_CheckNoticeOnNewMessage.StyleSelected = NoticeOnNewMessage;
  2978. }
  2979.  
  2980. // ---------------------------------- //
  2981. // Notice on new connection
  2982. if (NoticeOnConnection != Persistent_Evidence_NoticeOnConnection) {
  2983. NoticeOnConnection = Persistent_Evidence_NoticeOnConnection;
  2984. Quad_CheckNoticeOnConnection.StyleSelected = NoticeOnConnection;
  2985. }
  2986.  
  2987. // ---------------------------------- //
  2988. // Save Clipboard
  2989. if (Persistent_Evidence_PasteBin != TextEdit_PasteBin.Value)
  2990. Persistent_Evidence_PasteBin = TextEdit_PasteBin.Value;
  2991.  
  2992. // ---------------------------------- //
  2993. // Start next update check request
  2994. if (Now > NextUpdateCheckout) {
  2995. NextUpdateCheckout = Now + C_UpdateCheckInterval;
  2996.  
  2997. // Destroy ongoing request
  2998. if (UpdateCheckRequest != Null) {
  2999. Http.Destroy(UpdateCheckRequest);
  3000. UpdateCheckRequest = Null;
  3001. }
  3002.  
  3003. // Start new request
  3004. UpdateCheckRequest = Http.CreateGet(C_UpdateCheckAddress, False);
  3005. }
  3006.  
  3007. // ---------------------------------- //
  3008. // Display update notification
  3009. if (UpdateCheckRequest != Null && UpdateCheckRequest.IsCompleted) {
  3010. declare OnlineVersion = UpdateCheckRequest.Result;
  3011. PluginIsOutdated = (OnlineVersion != "" && OnlineVersion != "{{{ScriptVersion}}}");
  3012. if (PluginIsOutdated) SetModeNotificationsCount("Settings", 1);
  3013.  
  3014. Http.Destroy(UpdateCheckRequest);
  3015. UpdateCheckRequest = Null;
  3016. }
  3017.  
  3018. // Hold everything until chat is visible again
  3019. if (!ChatWidgetIsOpen) continue;
  3020.  
  3021. // ---------------------------------- //
  3022. // Update information
  3023. // ---------------------------------- //
  3024.  
  3025. // ---------------------------------- //
  3026. // Online buddies amount change
  3027. if (PrevBuddiesOnline != BuddiesList_Online.count) {
  3028. PrevBuddiesOnline = BuddiesList_Online.count;
  3029. SortBuddiesList = True;
  3030. }
  3031.  
  3032. // ---------------------------------- //
  3033. // Offline buddies amount change
  3034. if (PrevBuddiesOffline != BuddiesList_Offline.count) {
  3035. PrevBuddiesOffline = BuddiesList_Offline.count;
  3036. SortBuddiesList = True;
  3037. }
  3038.  
  3039. // ---------------------------------- //
  3040. // Incoming buddy requests amount change
  3041. if (PrevBuddiesRequestFrom != BuddiesList_RequestFrom.count) {
  3042. PrevBuddiesRequestFrom = BuddiesList_RequestFrom.count;
  3043. SortRequestsList = True;
  3044. SetModeNotificationsCount("Requests", PrevBuddiesRequestFrom);
  3045. }
  3046.  
  3047. // ---------------------------------- //
  3048. // Sent buddy requests amount change
  3049. if (PrevBuddiesRequestTo != BuddiesList_RequestTo.count) {
  3050. PrevBuddiesRequestTo = BuddiesList_RequestTo.count;
  3051. SortRequestsList = True;
  3052. }
  3053.  
  3054. // ---------------------------------- //
  3055. // Buddies in group amount change
  3056. if (PrevBuddiesInGroup != BuddiesList_InGroup.count) {
  3057. PrevBuddiesInGroup = BuddiesList_InGroup.count;
  3058. PagesCount["Group"] = (BuddiesList_InGroup.count - 1) / 10 + 1;
  3059. if (CurrentWidgetMode == "Group") UpdateBuddiesList = True;
  3060. }
  3061.  
  3062. // ---------------------------------- //
  3063. // Buddies in global chat amount change
  3064. if (PrevBuddiesGlobalList != BuddiesList_GlobalList.count) {
  3065. PrevBuddiesGlobalList = BuddiesList_GlobalList.count;
  3066. PagesCount["Global"] = (BuddiesList_GlobalList.count - 1) / 10 + 1;
  3067. if (CurrentWidgetMode == "Global") UpdateBuddiesList = True;
  3068. }
  3069.  
  3070. // ---------------------------------- //
  3071. // Muted buddies amount change
  3072. if (PrevBuddiesMutedUsers != BuddiesList_MutedUsers.count) {
  3073. PrevBuddiesMutedUsers = BuddiesList_MutedUsers.count;
  3074. if (CurrentWidgetMode == "Group") UpdateBuddiesList = True;
  3075. }
  3076.  
  3077. // ---------------------------------- //
  3078. // Buddy changed his name
  3079. foreach (Login => Name in BuddiesName) {
  3080. if (!PrevBuddiesName.existskey(Login) || PrevBuddiesName[Login] != Name) {
  3081. PrevBuddiesName[Login] = Name;
  3082. UpdateBuddiesList = True;
  3083.  
  3084. // Update messenger window
  3085. if (Login == SelectedConversation || CurrentWidgetMode == "Group" || CurrentWidgetMode == "Global") {
  3086. UpdateMessengerInfo = True;
  3087. UpdateMessagesSlots = 2;
  3088. }
  3089. }
  3090. }
  3091.  
  3092. // ---------------------------------- //
  3093. // Buddy changed his presence
  3094. foreach (Login => PresenceId in BuddiesPresenceId) {
  3095. if (!PrevBuddiesPresenceId.existskey(Login) || PrevBuddiesPresenceId[Login] != PresenceId) {
  3096. PrevBuddiesPresenceId[Login] = PresenceId;
  3097. SortBuddiesList = True;
  3098. UpdateBuddiesList = True;
  3099.  
  3100. // Update messenger window
  3101. if (Login == SelectedConversation || CurrentWidgetMode == "Group" || CurrentWidgetMode == "Global") {
  3102. UpdateMessengerInfo = True;
  3103. UpdateMessagesSlots = 2;
  3104. }
  3105. }
  3106. }
  3107.  
  3108. // ---------------------------------- //
  3109. // Buddy changed his status
  3110. foreach (Login => Status in BuddiesStatus) {
  3111. if (!PrevBuddiesStatus.existskey(Login) || PrevBuddiesStatus[Login] != Status) {
  3112. PrevBuddiesStatus[Login] = Status;
  3113. UpdateBuddiesList = True;
  3114.  
  3115. // Update messenger window
  3116. if (Login == SelectedConversation) UpdateMessengerInfo = True;
  3117. }
  3118. }
  3119.  
  3120. // ---------------------------------- //
  3121. // Buddy changed his server
  3122. foreach (Login => ServerLogin in BuddiesServerLogin) {
  3123. if (!PrevBuddiesServerLogin.existskey(Login) || PrevBuddiesServerLogin[Login] != ServerLogin) {
  3124. PrevBuddiesServerLogin[Login] = ServerLogin;
  3125. UpdateBuddiesList = True;
  3126.  
  3127. // Update messenger window
  3128. if (Login == SelectedConversation) UpdateMessengerInfo = True;
  3129. }
  3130. }
  3131.  
  3132. // ---------------------------------- //
  3133. // Global Chat users update
  3134. // ---------------------------------- //
  3135.  
  3136. // ---------------------------------- //
  3137. // User changed his name
  3138. foreach (Login => Name in GlobalChat_BuddiesName) {
  3139. if (!PrevGlobalBuddiesName.existskey(Login) || PrevGlobalBuddiesName[Login] != Name) {
  3140. PrevGlobalBuddiesName[Login] = Name;
  3141. UpdateBuddiesList = True;
  3142.  
  3143. // Update messenger window
  3144. if (CurrentWidgetMode == "Global") {
  3145. UpdateMessengerInfo = True;
  3146. UpdateMessagesSlots = 2;
  3147. }
  3148. }
  3149. }
  3150.  
  3151. // ---------------------------------- //
  3152. // User changed his presence
  3153. foreach (Login => PresenceId in GlobalChat_BuddiesPresenceId) {
  3154. if (!PrevGlobalBuddiesPresenceId.existskey(Login) || PrevGlobalBuddiesPresenceId[Login] != PresenceId) {
  3155. PrevGlobalBuddiesPresenceId[Login] = PresenceId;
  3156. UpdateBuddiesList = True;
  3157.  
  3158. // Update messenger window
  3159. if (CurrentWidgetMode == "Global") {
  3160. UpdateMessengerInfo = True;
  3161. UpdateMessagesSlots = 2;
  3162. }
  3163. }
  3164. }
  3165.  
  3166. // ---------------------------------- //
  3167. // Evidence widget
  3168. // ---------------------------------- //
  3169.  
  3170. // ---------------------------------- //
  3171. // Widget mode change
  3172. if (PrevWidgetMode != CurrentWidgetMode) {
  3173. UpdateModeButtons = True;
  3174. UpdateBuddiesList = True;
  3175. UpdateMessengerInfo = True;
  3176.  
  3177. // Set local user card visibility
  3178. declare ModesUsingLocalSlot = ["Buddies", "Group", "Global"];
  3179. Frame_LocalUserSlot.Visible = ModesUsingLocalSlot.exists(CurrentWidgetMode);
  3180. Frame_BuddyInviteCard.Visible = CurrentWidgetMode == "Requests";
  3181. Frame_SettingsMenu.Visible = CurrentWidgetMode == "Settings";
  3182. TextEdit_PasteBin.Visible = CurrentWidgetMode == "Settings";
  3183. Label_ButtonUpdate.Visible = (CurrentWidgetMode == "Settings" && PluginIsOutdated);
  3184.  
  3185. // Update messages slots
  3186. declare MessageUpdateModes = ["Group", "Global"];
  3187. if (MessageUpdateModes.exists(CurrentWidgetMode) || (MessageUpdateModes.exists(PrevWidgetMode) && SelectedConversation != "")) {
  3188. PrevMessengerIsOpen = False;
  3189. UpdateMessagesSlots = 2;
  3190. }
  3191.  
  3192. PrevWidgetMode = CurrentWidgetMode;
  3193. }
  3194.  
  3195. // ---------------------------------- //
  3196. // Set mode buttons color
  3197. if (UpdateModeButtons) {
  3198. UpdateModeButtons = False;
  3199. foreach (Mode => Frame in Frame_ModeButtons) {
  3200. declare Quad_ModeButtonIcon <=> (Frame.GetFirstChild("Quad_ModeButtonIcon") as CMlQuad);
  3201. Quad_ModeButtonIcon.Opacity = C_ModeButtonsOpacity[CurrentWidgetMode == Mode][(HighlightModeButton == Mode)];
  3202. }
  3203. }
  3204.  
  3205. // ---------------------------------- //
  3206. // Custom status updates
  3207. if (PrevEntryStatusValue != Entry_MessengerStatusInput.Value) {
  3208. PrevEntryStatusValue = Entry_MessengerStatusInput.Value;
  3209. Persistent_Evidence_UserCustomStatus = PrevEntryStatusValue;
  3210. ManialinkCustomStatus = PrevEntryStatusValue;
  3211. }
  3212.  
  3213. // ---------------------------------- //
  3214. // Force sort buddies list
  3215. if (SortBuddiesList) {
  3216. SortBuddiesList = False;
  3217. BuddiesList_SortedList.clear();
  3218. if (CurrentWidgetMode == "Buddies") UpdateBuddiesList = True;
  3219.  
  3220. // Online buddies listed on top
  3221. foreach (Login in BuddiesList_ListOnTop)
  3222. if (BuddiesList_Online.exists(Login)) BuddiesList_SortedList.add(Login);
  3223.  
  3224. // Other online buddies
  3225. foreach (Login in BuddiesList_Online)
  3226. if (!BuddiesList_SortedList.exists(Login)) BuddiesList_SortedList.add(Login);
  3227.  
  3228. // Offline buddies listed top
  3229. foreach (Login in BuddiesList_ListOnTop)
  3230. if (BuddiesList_Offline.exists(Login)) BuddiesList_SortedList.add(Login);
  3231.  
  3232. // Other offline buddies
  3233. foreach (Login in BuddiesList_Offline)
  3234. if (!BuddiesList_SortedList.exists(Login)) BuddiesList_SortedList.add(Login);
  3235.  
  3236. // Update pages amount
  3237. PagesCount["Buddies"] = (BuddiesList_SortedList.count - 1) / 10 + 1;
  3238. if (CurrentPage["Buddies"] > PagesCount["Buddies"]) CurrentPage["Buddies"] = PagesCount["Buddies"];
  3239. }
  3240.  
  3241. // ---------------------------------- //
  3242. // Force sort requests list
  3243. if (SortRequestsList) {
  3244. SortRequestsList = False;
  3245. BuddiesList_RequestList.clear();
  3246. if (CurrentWidgetMode == "Requests") UpdateBuddiesList = True;
  3247.  
  3248. foreach (Login in BuddiesList_RequestFrom) BuddiesList_RequestList.add(Login);
  3249. foreach (Login in BuddiesList_RequestTo) BuddiesList_RequestList.add(Login);
  3250.  
  3251. // Update pages amount
  3252. PagesCount["Requests"] = (BuddiesList_RequestList.count - 1) / 10 + 1;
  3253. if (CurrentPage["Requests"] > PagesCount["Requests"]) CurrentPage["Requests"] = PagesCount["Requests"];
  3254. }
  3255.  
  3256. // ---------------------------------- //
  3257. // Update buddies list slots
  3258. if (UpdateBuddiesList) {
  3259. UpdateBuddiesList = False;
  3260. UpdateSlotsBgSlots = True;
  3261.  
  3262. // ---------------------------------- //
  3263. // Configure page switch
  3264. declare ListCurrentPage = CurrentPage[CurrentWidgetMode];
  3265. declare ListPagesCount = PagesCount[CurrentWidgetMode];
  3266.  
  3267. Frame_PageSwitch.Visible = (ListPagesCount > 1);
  3268. if (Frame_PageSwitch.Visible) {
  3269. Label_PageSwitchCounter.SetText(ListCurrentPage^" / "^ListPagesCount);
  3270. Quad_PrevBuddiesPage.Visible = (ListCurrentPage > 1);
  3271. Quad_NextBuddiesPage.Visible = (ListCurrentPage < ListPagesCount);
  3272. }
  3273.  
  3274. // ---------------------------------- //
  3275. // Setup slots
  3276. declare ListPageIndexOffset = (ListCurrentPage - 1) * 10;
  3277. foreach (I => Frame in Frame_BuddiesSlots) {
  3278. declare BuddyId = I + ListPageIndexOffset;
  3279. declare Text BuddyLogin;
  3280.  
  3281. // ---------------------------------- //
  3282. // Get current buddy
  3283. switch (CurrentWidgetMode) {
  3284. case "Buddies" : {
  3285. if (BuddiesList_SortedList.existskey(BuddyId)) BuddyLogin = BuddiesList_SortedList[BuddyId];
  3286. }
  3287. case "Group" : {
  3288. if (BuddiesList_InGroup.existskey(BuddyId)) BuddyLogin = BuddiesList_InGroup[BuddyId];
  3289. }
  3290. case "Requests" : {
  3291. if (BuddiesList_RequestList.existskey(BuddyId)) BuddyLogin = BuddiesList_RequestList[BuddyId];
  3292. }
  3293. case "Global" : {
  3294. if (BuddiesList_GlobalList.existskey(BuddyId)) BuddyLogin = BuddiesList_GlobalList[BuddyId];
  3295. }
  3296. }
  3297.  
  3298. Frame.Visible = (BuddyLogin != "");
  3299. if (!Frame.Visible) continue;
  3300.  
  3301. // ---------------------------------- //
  3302. // Load buddy slot elements
  3303. declare Quad_BuddySlotBgCard <=> (Frame.GetFirstChild("Quad_BuddySlotBgCard") as CMlQuad);
  3304. declare Label_BuddySlotName <=> (Frame.GetFirstChild("Label_BuddySlotName") as CMlLabel);
  3305. declare Quad_BuddySlotPresence <=> (Frame.GetFirstChild("Quad_BuddySlotPresence") as CMlQuad);
  3306. declare Quad_BuddySlotGlow <=> (Frame.GetFirstChild("Quad_BuddySlotGlow") as CMlQuad);
  3307. declare Label_BuddySlotStatus <=> (Frame.GetFirstChild("Label_BuddySlotStatus") as CMlLabel);
  3308. declare Quad_BuddySlotBtnJoin <=> (Frame.GetFirstChild("Quad_BuddySlotBtnJoin") as CMlQuad);
  3309. declare Quad_BuddySlotBtnAdd <=> (Frame.GetFirstChild("Quad_BuddySlotBtnAdd") as CMlQuad);
  3310. declare Quad_BuddySlotBtnDeny <=> (Frame.GetFirstChild("Quad_BuddySlotBtnDeny") as CMlQuad);
  3311. declare Quad_BuddySlotBtnKick <=> (Frame.GetFirstChild("Quad_BuddySlotBtnKick") as CMlQuad);
  3312. declare Quad_BuddySlotBtnMute <=> (Frame.GetFirstChild("Quad_BuddySlotBtnMute") as CMlQuad);
  3313.  
  3314. // ---------------------------------- //
  3315. // Set buddy name
  3316. declare BuddyName = BuddyLogin;
  3317. if (BuddiesName.existskey(BuddyLogin)) BuddyName = BuddiesName[BuddyLogin];
  3318. else if (GlobalChat_BuddiesName.existskey(BuddyLogin)) BuddyName = GlobalChat_BuddiesName[BuddyLogin];
  3319. Label_BuddySlotName.SetText(BuddyName);
  3320.  
  3321. // ---------------------------------- //
  3322. // Set buddy presence
  3323. declare BuddyPresenceId = 0;
  3324. if (BuddiesPresenceId.existskey(BuddyLogin)) BuddyPresenceId = BuddiesPresenceId[BuddyLogin];
  3325. else if (GlobalChat_BuddiesPresenceId.existskey(BuddyLogin)) BuddyPresenceId = GlobalChat_BuddiesPresenceId[BuddyLogin];
  3326. Quad_BuddySlotPresence.BgColor = C_UserPresenceColors[BuddyPresenceId];
  3327. Quad_BuddySlotGlow.Colorize = Quad_BuddySlotPresence.BgColor;
  3328. Quad_BuddySlotGlow.Visible = (BuddyPresenceId > 0);
  3329.  
  3330. // ---------------------------------- //
  3331. // Set buddy status text
  3332. declare BuddyStatus = C_UserPresenceStatus[BuddyPresenceId];
  3333.  
  3334. // Put server name or login in buddy status
  3335. if (BuddiesServerLogin.existskey(BuddyLogin) && BuddiesServerLogin[BuddyLogin] != "") {
  3336. declare ServerLogin = BuddiesServerLogin[BuddyLogin];
  3337. if (!ServersName.existskey(ServerLogin)) BuddyStatus = ServerLogin;
  3338. else BuddyStatus = ServersName[ServerLogin];
  3339. }
  3340. // Put buddys own status
  3341. else if (BuddiesStatus.existskey(BuddyLogin) && BuddiesStatus[BuddyLogin] != "")
  3342. BuddyStatus = BuddiesStatus[BuddyLogin];
  3343. // Put Global Chat buddy status
  3344. else if (GlobalChat_BuddiesStatus.existskey(BuddyLogin) && GlobalChat_BuddiesStatus[BuddyLogin] != "")
  3345. BuddyStatus = GlobalChat_BuddiesStatus[BuddyLogin];
  3346.  
  3347. Label_BuddySlotStatus.SetText(BuddyStatus);
  3348.  
  3349. // ---------------------------------- //
  3350. // Setup background
  3351. Quad_BuddySlotBgCard.DataAttributeSet("login", BuddyLogin);
  3352.  
  3353. // ---------------------------------- //
  3354. // Setup join button
  3355. Quad_BuddySlotBtnJoin.Visible = (
  3356. CurrentWidgetMode == "Buddies" &&
  3357. BuddiesJoinLink.existskey(BuddyLogin) && BuddiesJoinLink[BuddyLogin] != ""
  3358. );
  3359. if (Quad_BuddySlotBtnJoin.Visible)
  3360. Quad_BuddySlotBtnJoin.DataAttributeSet("manialink", BuddiesJoinLink[BuddyLogin]);
  3361.  
  3362. // ---------------------------------- //
  3363. // Accept / refuse buttons
  3364. Quad_BuddySlotBtnDeny.Visible = (CurrentWidgetMode == "Requests");
  3365. Quad_BuddySlotBtnAdd.Visible = (CurrentWidgetMode == "Requests" && BuddiesList_RequestFrom.exists(BuddyLogin));
  3366.  
  3367. Quad_BuddySlotBtnDeny.DataAttributeSet("login", BuddyLogin);
  3368. Quad_BuddySlotBtnAdd.DataAttributeSet("login", BuddyLogin);
  3369.  
  3370. if (Quad_BuddySlotBtnAdd.Visible) Label_BuddySlotStatus.SetText("Incoming invitation");
  3371. else if (Quad_BuddySlotBtnDeny.Visible) Label_BuddySlotStatus.SetText(_("Sent invitation"));
  3372.  
  3373. // ---------------------------------- //
  3374. // Kick from the group button
  3375. Quad_BuddySlotBtnKick.Visible = (CurrentWidgetMode == "Group");
  3376. if (Quad_BuddySlotBtnKick.Visible)
  3377. Quad_BuddySlotBtnKick.DataAttributeSet("command", "/kick "^BuddyLogin);
  3378.  
  3379. // ---------------------------------- //
  3380. // Mute user button
  3381. Quad_BuddySlotBtnMute.Visible = (CurrentWidgetMode == "Group");
  3382. if (Quad_BuddySlotBtnMute.Visible) {
  3383. declare BuddyIsMuted = BuddiesList_MutedUsers.exists(BuddyLogin);
  3384. Quad_BuddySlotBtnMute.ImageUrl = C_SlotMuteButtonImages[BuddyIsMuted][False];
  3385. Quad_BuddySlotBtnMute.ImageUrlFocus = C_SlotMuteButtonImages[BuddyIsMuted][True];
  3386.  
  3387. if (!BuddyIsMuted) Quad_BuddySlotBtnMute.DataAttributeSet("command", "/mute "^BuddyLogin);
  3388. else Quad_BuddySlotBtnMute.DataAttributeSet("command", "/unmute "^BuddyLogin);
  3389. }
  3390. }
  3391. }
  3392.  
  3393. // ---------------------------------- //
  3394. // Update buddies slots backgrounds colors
  3395. if (UpdateSlotsBgSlots) {
  3396. UpdateSlotsBgSlots = False;
  3397. Quad_LocalUserBgCard.BgColor = C_BuddySlotBgColors[False][Quad_LocalUserBgCard.Id == HighlightBuddySlot];
  3398.  
  3399. declare Modes = ["Buddies", "Requests"];
  3400. foreach (Frame in Frame_BuddiesSlots) {
  3401. if (!Frame.Visible) continue;
  3402. declare Quad_BuddySlotBgCard <=> (Frame.GetFirstChild("Quad_BuddySlotBgCard") as CMlQuad);
  3403. declare BuddyLogin = Quad_BuddySlotBgCard.DataAttributeGet("login");
  3404.  
  3405. declare SlotIsSelected = (Modes.exists(CurrentWidgetMode) && SelectedConversation == BuddyLogin);
  3406. Quad_BuddySlotBgCard.BgColor = C_BuddySlotBgColors[SlotIsSelected][(Quad_BuddySlotBgCard.Id == HighlightBuddySlot)];
  3407. }
  3408. }
  3409.  
  3410. // ---------------------------------- //
  3411. // Blink buddies cards on new messages
  3412. foreach (Frame in Frame_BuddiesSlots) {
  3413. if (!Frame.Visible) continue;
  3414. declare Quad_BuddySlotBgCard <=> (Frame.GetFirstChild("Quad_BuddySlotBgCard") as CMlQuad);
  3415. declare Quad_BuddySlotBlink <=> (Frame.GetFirstChild("Quad_BuddySlotBlink") as CMlQuad);
  3416. declare Label_BuddySlotNbNotice <=> (Frame.GetFirstChild("Label_BuddySlotNbNotice") as CMlLabel);
  3417. declare BuddyLogin = Quad_BuddySlotBgCard.DataAttributeGet("login");
  3418.  
  3419. // Get amount of unread messages from slot buddy
  3420. declare Integer BuddyNbUnreadMessages;
  3421. if (Persistent_Evidence_NbUnreadMessages.existskey(BuddyLogin))
  3422. BuddyNbUnreadMessages = Persistent_Evidence_NbUnreadMessages[BuddyLogin];
  3423.  
  3424. // Blink card background
  3425. if (BuddyNbUnreadMessages <= 0) Quad_BuddySlotBlink.Opacity = 0.;
  3426. else Quad_BuddySlotBlink.Opacity = Pulse(Now, 1.) / 2;
  3427.  
  3428. // Set unread messages counter
  3429. Label_BuddySlotNbNotice.Visible = (BuddyNbUnreadMessages > 0);
  3430. if (Label_BuddySlotNbNotice.Visible)
  3431. Label_BuddySlotNbNotice.Value = TL::ToText(BuddyNbUnreadMessages);
  3432. }
  3433.  
  3434. if (Frame_LocalUserSlot.Visible) {
  3435. // ---------------------------------- //
  3436. // Update local user name
  3437. if (Label_LocalUserBgName.Value != LocalUser.Name) {
  3438. Label_LocalUserBgName.SetText(LocalUser.Name);
  3439. if (CurrentWidgetMode == "Group") UpdateMessengerInfo = True;
  3440. }
  3441.  
  3442. // ---------------------------------- //
  3443. // Update local presence light
  3444. if (PrevPluginPresenceId != CurrentPluginPresenceId) {
  3445. PrevPluginPresenceId = CurrentPluginPresenceId;
  3446. if (CurrentWidgetMode == "Group") UpdateMessengerInfo = True;
  3447.  
  3448. if (CurrentPluginPresenceId >= 0) {
  3449. Quad_LocalUserPresence.BgColor = C_UserPresenceColors[CurrentPluginPresenceId];
  3450. Quad_LocalUserGlow.Visible = (CurrentPluginPresenceId > 0);
  3451. Quad_LocalUserGlow.Colorize = Quad_LocalUserPresence.BgColor;
  3452. }
  3453. }
  3454.  
  3455. // ---------------------------------- //
  3456. // Update local user status
  3457. if (Label_LocalUserStatus.Value != CurrentPluginStatusText) {
  3458. Label_LocalUserStatus.SetText(CurrentPluginStatusText);
  3459. if (CurrentWidgetMode == "Group") UpdateMessengerInfo = True;
  3460. }
  3461. }
  3462.  
  3463. // ---------------------------------- //
  3464. // Update mails amount
  3465. if (PrevLegacyMailsAmount != LegacyMailsAmount) {
  3466. PrevLegacyMailsAmount = LegacyMailsAmount;
  3467. SetModeNotificationsCount("Mailbox", LegacyMailsAmount);
  3468. }
  3469.  
  3470. // ---------------------------------- //
  3471. // Change add buddy button visibility
  3472. if (Frame_BuddyInviteCard.Visible) {
  3473. Quad_InvitePlayerButton.Visible = (Entry_InvitePlayerInput.Value != "");
  3474. }
  3475.  
  3476. // Dont update messenger if it's hidden
  3477. if (!MessengerIsOpen) continue;
  3478.  
  3479. // ---------------------------------- //
  3480. // Messenger window
  3481. // ---------------------------------- //
  3482.  
  3483. // ---------------------------------- //
  3484. // Update messenger on conversation change
  3485. if (PrevSelectedConversation != SelectedConversation) {
  3486. PrevSelectedConversation = SelectedConversation;
  3487. UpdateMessagesSlots = 2;
  3488. UpdateMessengerInfo = True;
  3489. if (SelectedConversation != "") PrevMessengerIsOpen = False;
  3490. }
  3491.  
  3492. // ---------------------------------- //
  3493. // Update messages Slots
  3494. if (UpdateMessagesSlots > 0) {
  3495. UpdateMessagesSlots -= 1;
  3496. declare CurrentOffsetY = 0.;
  3497.  
  3498. // ---------------------------------- //
  3499. // Select active conversation
  3500. declare Text BuddyLogin;
  3501. switch (CurrentWidgetMode) {
  3502. case "Group" : BuddyLogin = "*group*";
  3503. case "Global" : BuddyLogin = "*global*";
  3504. default : BuddyLogin = SelectedConversation;
  3505. }
  3506.  
  3507. // Reset unread messages amount
  3508. if (Persistent_Evidence_NbUnreadMessages.existskey(BuddyLogin))
  3509. Persistent_Evidence_NbUnreadMessages[BuddyLogin] = 0;
  3510.  
  3511. // Init history if empty
  3512. if (!Persistent_Evidence_ChatHistory.existskey(BuddyLogin))
  3513. Persistent_Evidence_ChatHistory[BuddyLogin] = Text[][];
  3514.  
  3515. // ---------------------------------- //
  3516. // Setup scrolling buttons
  3517. declare MessageOffset = 0;
  3518. if (MessagesOffset.existskey(BuddyLogin)) MessageOffset = MessagesOffset[BuddyLogin];
  3519.  
  3520. Quad_MessagesScrollUp.Visible = (MessageOffset < Persistent_Evidence_ChatHistory[BuddyLogin].count - 1);
  3521. Quad_MessagesScrollDown.Visible = (MessageOffset > 0);
  3522.  
  3523. foreach (I => Frame in Frame_MessagesSlots) {
  3524. // ---------------------------------- //
  3525. // Load message from history
  3526. declare Text[] MessageData;
  3527. if (Persistent_Evidence_ChatHistory.existskey(BuddyLogin)) {
  3528. declare Index = Persistent_Evidence_ChatHistory[BuddyLogin].count - 1 - I - MessageOffset;
  3529. if (Persistent_Evidence_ChatHistory[BuddyLogin].existskey(Index))
  3530. MessageData = Persistent_Evidence_ChatHistory[BuddyLogin][Index];
  3531.  
  3532.  
  3533. }
  3534.  
  3535. Frame.Visible = (MessageData.count >= 2);
  3536. if (!Frame.Visible) continue;
  3537.  
  3538. // Message primary data
  3539. declare SenderLogin = MessageData[0];
  3540. declare MessageBody = MessageData[1];
  3541.  
  3542. // ---------------------------------- //
  3543. // Load message slot elements
  3544. declare Quad_MessageSlotBgCard <=> (Frame.GetFirstChild("Quad_MessageSlotBgCard") as CMlQuad);
  3545. declare Label_MessageSlotName <=> (Frame.GetFirstChild("Label_MessageSlotName") as CMlLabel);
  3546. declare Label_MessageSlotBody <=> (Frame.GetFirstChild("Label_MessageSlotBody") as CMlLabel);
  3547. declare Label_MessageSlotTime <=> (Frame.GetFirstChild("Label_MessageSlotTime") as CMlLabel);
  3548. declare Quad_MessageSlotBtnCopy <=> (Frame.GetFirstChild("Quad_MessageSlotBtnCopy") as CMlQuad);
  3549.  
  3550. // Set sender login
  3551. declare SenderName = SenderLogin;
  3552. if (SenderLogin == "") SenderName = "$t$888Evidence";
  3553. else if (SenderLogin == LocalUser.Login) SenderName = LocalUser.Name;
  3554. else if (BuddiesName.existskey(SenderLogin)) SenderName = BuddiesName[SenderLogin];
  3555. else if (GlobalChat_BuddiesName.existskey(SenderLogin)) SenderName = GlobalChat_BuddiesName[SenderLogin];
  3556. Label_MessageSlotName.SetText(SenderName);
  3557.  
  3558. // Message body
  3559. Label_MessageSlotBody.SetText(MessageBody);
  3560.  
  3561. // Message time
  3562. declare Text MessageTime;
  3563. if (MessageData.existskey(2)) MessageTime = MessageData[2];
  3564. Label_MessageSlotTime.SetText(MessageTime);
  3565.  
  3566. // Sender presence
  3567. if (SenderLogin == LocalUser.Login || SenderLogin == "") Quad_MessageSlotBgCard.BgColor = <0., 0., 0.>;
  3568. else if (BuddiesPresenceId.existskey(SenderLogin))
  3569. Quad_MessageSlotBgCard.BgColor = C_UserPresenceColors[BuddiesPresenceId[SenderLogin]];
  3570. else if (GlobalChat_BuddiesPresenceId.existskey(SenderLogin))
  3571. Quad_MessageSlotBgCard.BgColor = C_UserPresenceColors[GlobalChat_BuddiesPresenceId[SenderLogin]];
  3572. else
  3573. Quad_MessageSlotBgCard.BgColor = C_UserPresenceColors[0];
  3574.  
  3575. // Copy button
  3576. Quad_MessageSlotBtnCopy.DataAttributeSet("clipboard", Label_MessageSlotBody.Value);
  3577.  
  3578. // ---------------------------------- //
  3579. // Frame position
  3580. declare PositionX = 0.;
  3581. if (SenderLogin == LocalUser.Login) PositionX = 8.;
  3582. Frame.RelativePosition.X = PositionX;
  3583.  
  3584. Quad_MessageSlotBgCard.Size.Y = 3 * Label_MessageSlotBody.ValueLineCount + 4.5;
  3585. CurrentOffsetY += Quad_MessageSlotBgCard.Size.Y + .5;
  3586. Frame.RelativePosition.Y = CurrentOffsetY;
  3587. }
  3588. }
  3589.  
  3590. // ---------------------------------- //
  3591. // Update info on Global Chat connection change
  3592. if (PrevGlobalChatConnectionStatus != GlobalChat_ConnectionStatus) {
  3593. PrevGlobalChatConnectionStatus = GlobalChat_ConnectionStatus;
  3594. UpdateMessengerInfo = True;
  3595. }
  3596.  
  3597. // ---------------------------------- //
  3598. // Update name and status of curreent conversation buddy
  3599. if (UpdateMessengerInfo) {
  3600. UpdateMessengerInfo = False;
  3601.  
  3602. // ---------------------------------- //
  3603. // Set conversation name
  3604. declare Text ConversationName;
  3605. declare Text ConversationLogin;
  3606.  
  3607. switch (CurrentWidgetMode) {
  3608. case "Group" : {
  3609. ConversationName = LocalUser.Name;
  3610. ConversationLogin = LocalUser.Login;
  3611. }
  3612. case "Global" : ConversationName = "Evidence Global Chat";
  3613. default : {
  3614. ConversationLogin = SelectedConversation;
  3615. if (BuddiesName.existskey(ConversationLogin)) ConversationName = BuddiesName[ConversationLogin];
  3616. else ConversationName = ConversationLogin;
  3617. }
  3618. }
  3619.  
  3620. Label_MessengerBuddyName.SetText(ConversationName);
  3621.  
  3622. // ---------------------------------- //
  3623. // Set conversation presence
  3624. declare Integer PresenceId;
  3625. switch (CurrentWidgetMode) {
  3626. case "Group" : PresenceId = CurrentPluginPresenceId;
  3627. case "Global" : PresenceId = GlobalChat_ConnectionStatus;
  3628. default : {
  3629. if (BuddiesPresenceId.existskey(ConversationLogin)) PresenceId = BuddiesPresenceId[ConversationLogin];
  3630. }
  3631. }
  3632. if (PresenceId >= 0) Quad_MessengerBuddyPresence.Colorize = C_UserPresenceColors[PresenceId];
  3633.  
  3634. // ---------------------------------- //
  3635. // Set conversation status
  3636. Label_MessengerBuddyStatus.Visible = (CurrentWidgetMode != "Group");
  3637. if (Label_MessengerBuddyStatus.Visible) {
  3638. declare StatusText = C_UserPresenceStatus[0];
  3639. switch (CurrentWidgetMode) {
  3640. case "Global" : StatusText = C_GlobalChatConnectionStatus[GlobalChat_ConnectionStatus];
  3641. default : {
  3642. if (BuddiesStatus.existskey(ConversationLogin)) StatusText = BuddiesStatus[ConversationLogin];
  3643. }
  3644. }
  3645. Label_MessengerBuddyStatus.SetText(StatusText);
  3646. }
  3647.  
  3648. // ---------------------------------- //
  3649. // Show status edition field
  3650. Entry_MessengerStatusInput.Visible = (CurrentWidgetMode == "Group");
  3651. if (Entry_MessengerStatusInput.Visible) {
  3652. Entry_MessengerStatusInput.Value = ManialinkCustomStatus;
  3653. }
  3654.  
  3655. // ---------------------------------- //
  3656. // Configure action buttons
  3657. Frame_MessengerBuddyActions.Visible = (CurrentWidgetMode != "Group" && CurrentWidgetMode != "Global");
  3658. if (Frame_MessengerBuddyActions.Visible) {
  3659. // ---------------------------------- //
  3660. // Set buddy login
  3661. Label_MessengerBuddyLogin.SetText(ConversationLogin);
  3662.  
  3663. // ---------------------------------- //
  3664. // Set buddy server name
  3665. declare ServerName = _("Not playing on a server");
  3666. if (BuddiesServerLogin.existskey(ConversationLogin) && BuddiesServerLogin[ConversationLogin] != "") {
  3667. declare ServerLogin = BuddiesServerLogin[ConversationLogin];
  3668. if (!ServersName.existskey(ServerLogin)) ServerName = ServerLogin;
  3669. else ServerName = ServersName[ServerLogin];
  3670. }
  3671. Label_MessengerBuddyServer.SetText(ServerName);
  3672.  
  3673. // ---------------------------------- //
  3674. // Setup join button
  3675. Quad_MessengerBuddyJoin.Visible = (BuddiesJoinLink.existskey(ConversationLogin) && BuddiesJoinLink[ConversationLogin] != "");
  3676. if (Quad_MessengerBuddyJoin.Visible)
  3677. Quad_MessengerBuddyJoin.DataAttributeSet("manialink", BuddiesJoinLink[ConversationLogin]);
  3678.  
  3679. // ---------------------------------- //
  3680. // Setup mail button
  3681. Quad_MessengerBuddyMail.DataAttributeSet("login", ConversationLogin);
  3682.  
  3683. // ---------------------------------- //
  3684. // Setup remove button
  3685. Quad_MessengerBuddyRemove.DataAttributeSet("login", ConversationLogin);
  3686. }
  3687. }
  3688. ***
  3689.  
  3690. // ---------------------------------- //
  3691. // Functions
  3692. // ---------------------------------- //
  3693.  
  3694. // ---------------------------------- //
  3695. /** Compute width of the label text
  3696. *
  3697. * @param _Label Label to check text length
  3698.  
  3699. * @return Width of the label text
  3700. */
  3701. Real ComputeWidth(CMlLabel _Label) {
  3702. if (_Label == Null) return 0.;
  3703. return _Label.ComputeWidth(_Label.Value) * _Label.RelativeScale;
  3704. }
  3705.  
  3706. // ---------------------------------- //
  3707. /** Change number of notifications in mode button
  3708. *
  3709. * @param _Mode Mode to set noticifications amount
  3710. * @param _NotificationsCount Amount of the notifications to set
  3711. */
  3712. Void SetModeNotificationsCount(Text _Mode, Integer _NotificationsCount) {
  3713. if (!C_ChatWidgetModes.exists(_Mode)) return;
  3714. declare Frame <=> (Page.GetFirstChild("Frame_ModeButton"^_Mode) as CMlFrame);
  3715. declare Frame_ModeButtonNotice <=> (Frame.GetFirstChild("Frame_ModeButtonNotice") as CMlFrame);
  3716. declare Label_ModeButtonNotice <=> (Frame.GetFirstChild("Label_ModeButtonNotice") as CMlLabel);
  3717.  
  3718. Frame_ModeButtonNotice.Visible = (_NotificationsCount > 0);
  3719. if (Frame_ModeButtonNotice.Visible)
  3720. Label_ModeButtonNotice.SetText(TL::ToText(_NotificationsCount));
  3721. }
  3722.  
  3723. // ---------------------------------- //
  3724. /** Return pulse value for animations
  3725. *
  3726. * @param _Time Time of the pulse animations
  3727. * @param _Frequency Frequency of the pulse in Hz
  3728. *
  3729. * @return Pulse animation value
  3730. */
  3731. Real Pulse(Integer _Time, Real _Frequency) {
  3732. return (ML::Sin(ML::PI() * 2 * (_Time / 1000.) * _Frequency) + 1) / 2;
  3733. }
  3734.  
  3735. // ---------------------------------- //
  3736. /** Detect and automatically format sent and received URLs
  3737. *
  3738. * @param _InputText Text to find and format URLs
  3739. *
  3740. * @return Formatted text
  3741. */
  3742. Text AutoFormatURL(Text _InputText) {
  3743. if (_InputText == "") return "";
  3744. declare TextObjects = TL::Split(" ", _InputText);
  3745. declare Text OutputText;
  3746.  
  3747. foreach (I => Object in TextObjects) {
  3748. if (I > 0) OutputText ^= " ";
  3749.  
  3750. // HTTP
  3751. if (TL::SubString(Object, 0, 7) == "http://") OutputText ^= "$FA3$l"^Object^"$z";
  3752.  
  3753. // HTTPS
  3754. else if (TL::SubString(Object, 0, 8) == "https://") OutputText ^= "$FA3$l"^Object^"$z";
  3755.  
  3756. // WWW
  3757. else if (TL::SubString(Object, 0, 4) == "www.") OutputText ^= "$FA3$l"^Object^"$z";
  3758.  
  3759. // Manialink
  3760. else if (TL::SubString(Object, 0, 14) == "maniaplanet://") OutputText ^= "$6BF$h"^Object^"$z";
  3761.  
  3762. // ManiapPanet action
  3763. else if (TL::SubString(Object, 0, 1) == "#") OutputText ^= "$6BF$h"^Object^"$z";
  3764.  
  3765. // No address
  3766. else OutputText ^= Object;
  3767. }
  3768.  
  3769. return OutputText;
  3770. }
  3771.  
  3772. // ---------------------------------- //
  3773. /** Format message with buily-in functions
  3774. *
  3775. * @param _Message Message to format
  3776. *
  3777. * @return Formatted message
  3778. */
  3779. Text FormatMessage(Text _Message) {
  3780. if (_Message == "") return "";
  3781. declare OutputMessage = _Message;
  3782.  
  3783. // ---------------------------------- //
  3784. // Phrase links
  3785. declare persistent Boolean Persistent_Evidence_UseLinksPhrasing for Page = True;
  3786. if (Persistent_Evidence_UseLinksPhrasing) OutputMessage = AutoFormatURL(OutputMessage);
  3787.  
  3788. return OutputMessage;
  3789. }
  3790.  
  3791. // ---------------------------------- //
  3792. // Main
  3793. // ---------------------------------- //
  3794. main() {
  3795. wait(LocalUser != Null);
  3796. +++Main+++
  3797. while (True) {
  3798. yield;
  3799. +++Yield+++
  3800. }
  3801. }
  3802. --></script>
  3803. </manialink>""";
  3804. }
  3805.  
  3806. Text CreateManialinkNotifications() {
  3807. return """
  3808. <manialink version="2" name="Evidence:Notifications" background="0">
  3809. <framemodel id="FrameModel_Notification">
  3810. <quad posn="-4" sizen="80 7.5" style="Bgs1InRace" substyle="BgGradLeft"/>
  3811. <quad posn="-4" sizen="80 7.5" style="Bgs1InRace" substyle="BgGradLeft"/>
  3812. <quad posn="1 -3.75 1" sizen="6 6" valign="center" id="Quad_NoticeIcon"/>
  3813. <label posn="8 -2.125 1" sizen="33.5 3" valign="center2" scale=".9" textsize="1" textemboss="1" textcolor="AAA" id="Label_NoticeHeader"/>
  3814. <label posn="8 -5.125 1" sizen="48.5 3" valign="center2" textsize="1" textemboss="1" textcolor="FFF" maxline="1" id="Label_NoticeBody"/>
  3815. </framemodel>
  3816.  
  3817. <frame id="Frame_Notifications" posn="-160 89.5">
  3818. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#0" hidden="1"/>
  3819. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#1" hidden="1"/>
  3820. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#2" hidden="1"/>
  3821. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#3" hidden="1"/>
  3822. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#4" hidden="1"/>
  3823. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#5" hidden="1"/>
  3824. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#6" hidden="1"/>
  3825. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#7" hidden="1"/>
  3826. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#8" hidden="1"/>
  3827. <frameinstance modelid="FrameModel_Notification" id="Frame_Notification#9" hidden="1"/>
  3828. </frame>
  3829.  
  3830. <script><!--
  3831. /**
  3832. * EVIDENCE by domino54
  3833. * Notifications manialink
  3834. */
  3835.  
  3836. #Include "TextLib" as TL
  3837.  
  3838. #Const C_MaxNbNotifications 10
  3839. #Const C_NoticeDisplayTime 6500
  3840.  
  3841. // ---------------------------------- //
  3842. // Main
  3843. // ---------------------------------- //
  3844. ***Main***
  3845. ***
  3846. // ---------------------------------- //
  3847. // Load interface elements
  3848. declare Frame_Notices <=> (Page.GetFirstChild("Frame_Notifications") as CMlFrame);
  3849.  
  3850. declare CMlFrame[] Frame_Notifications;
  3851. for (I, 0, C_MaxNbNotifications - 1)
  3852. Frame_Notifications.add((Page.GetFirstChild("Frame_Notification#"^I) as CMlFrame));
  3853.  
  3854. // ---------------------------------- //
  3855. // Plugin shared variables
  3856. declare Text[][] NewNotifications for Page; ///< New notifications to display
  3857. declare Boolean ToolbarActive for Page; ///< ManiaPlanet toolbar visibility
  3858.  
  3859. // ---------------------------------- //
  3860. // Variables
  3861. declare Text[][Integer] CurrentNotifications;
  3862. declare Integer[] NotificationsToRemove;
  3863. declare Boolean UpdateNotifications;
  3864.  
  3865. declare PrevToolbarActive = False;
  3866. ***
  3867.  
  3868. // ---------------------------------- //
  3869. // Yield
  3870. // ---------------------------------- //
  3871. ***Yield***
  3872. ***
  3873. // ---------------------------------- //
  3874. // Save new notifications
  3875. while (NewNotifications.count > 0) {
  3876. declare NoticeData = NewNotifications[0];
  3877. CurrentNotifications[Now] = NoticeData;
  3878. declare Removed = NewNotifications.removekey(0);
  3879. UpdateNotifications = True;
  3880.  
  3881. // ---------------------------------- //
  3882. // Remove oldest notification if there are too many
  3883. if (CurrentNotifications.count > C_MaxNbNotifications) {
  3884. declare OldestNoticeTime = 0;
  3885. foreach (Time => NoticeData in CurrentNotifications)
  3886. if (OldestNoticeTime == 0) OldestNoticeTime = Time;
  3887. CurrentNotifications.removekey(OldestNoticeTime);
  3888. }
  3889. }
  3890.  
  3891. // ---------------------------------- //
  3892. // Remove old notifications
  3893. foreach (Time => NoticeData in CurrentNotifications) {
  3894. if (Now >= Time + C_NoticeDisplayTime) NotificationsToRemove.add(Time);
  3895. }
  3896. if (NotificationsToRemove.count > 0) {
  3897. UpdateNotifications = True;
  3898. for (I, 0, NotificationsToRemove.count - 1) {
  3899. declare Removed1 = CurrentNotifications.removekey(NotificationsToRemove[0]);
  3900. declare Removed2 = NotificationsToRemove.removekey(0);
  3901. }
  3902. }
  3903.  
  3904. // ---------------------------------- //
  3905. // Update notifications models
  3906. if (UpdateNotifications) {
  3907. UpdateNotifications = False;
  3908.  
  3909. // ---------------------------------- //
  3910. // Hide all frames
  3911. foreach (Frame in Frame_Notifications) {
  3912. Frame.RelativePosition.Y = 0.;
  3913. Frame.Hide();
  3914. }
  3915.  
  3916. declare Integer I;
  3917. foreach (NoticeData in CurrentNotifications) {
  3918. declare Frame = Frame_Notifications[I];
  3919. declare Label_NoticeHeader <=> (Frame.GetFirstChild("Label_NoticeHeader") as CMlLabel);
  3920. declare Label_NoticeBody <=> (Frame.GetFirstChild("Label_NoticeBody") as CMlLabel);
  3921. declare Quad_NoticeIcon <=> (Frame.GetFirstChild("Quad_NoticeIcon") as CMlQuad);
  3922.  
  3923. // ---------------------------------- //
  3924. // Set notice text
  3925. Label_NoticeHeader.SetText(NoticeData[0]);
  3926. Label_NoticeBody.SetText(NoticeData[1]);
  3927.  
  3928. // ---------------------------------- //
  3929. // Set icon
  3930. if (TL::Find("|", NoticeData[2], False, False)) {
  3931. declare SplitStyle = TL::Split("|", NoticeData[2]);
  3932. Quad_NoticeIcon.Style = SplitStyle[0];
  3933. Quad_NoticeIcon.Substyle = SplitStyle[1];
  3934. Quad_NoticeIcon.ImageUrl = "";
  3935. } else {
  3936. Quad_NoticeIcon.ImageUrl = NoticeData[2];
  3937. }
  3938.  
  3939. // ---------------------------------- //
  3940. // Move other notifications
  3941. foreach (Frame_Notification in Frame_Notifications)
  3942. if (Frame_Notification.Visible) Frame_Notification.RelativePosition.Y -= 8.;
  3943.  
  3944. Frame.Show();
  3945. I += 1;
  3946. }
  3947. }
  3948.  
  3949. // ---------------------------------- //
  3950. // Update notifications position
  3951. if (PrevToolbarActive != ToolbarActive) {
  3952. PrevToolbarActive = ToolbarActive;
  3953.  
  3954. Frame_Notices.RelativePosition.Y = 89.5;
  3955. if (ToolbarActive) Frame_Notices.RelativePosition.Y -= 6.;
  3956. }
  3957. ***
  3958.  
  3959. // ---------------------------------- //
  3960. // Main
  3961. // ---------------------------------- //
  3962. main() {
  3963. +++Main+++
  3964. while (True) {
  3965. yield;
  3966. +++Yield+++
  3967. }
  3968. }
  3969. --></script>
  3970. </manialink>""";
  3971. }
  3972.  
  3973. // ---------------------------------- //
  3974. // Main
  3975. // ---------------------------------- //
  3976. main() {
  3977. +++Main+++
  3978. +++GlobalChatStart+++
  3979. while (True) {
  3980. +++Yield+++
  3981. // +++GlobalChatYield+++
  3982. yield;
  3983. }
  3984. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement