From 69614da8cbf3cb947d6a5028c97a31a2d9b7abae Mon Sep 17 00:00:00 2001 From: AndreFaramir Date: Tue, 1 May 2012 03:49:48 -0300 Subject: [PATCH] New module and changes * Implementing rule violation interface * New popup menu on console text messages * Terminal and Console will no longer history double command/messages --- modules/client_terminal/terminal.lua | 8 +- modules/game/game.otmod | 1 + modules/game/gameinterface.lua | 5 + modules/game_console/console.lua | 54 +++++-- modules/game_ruleviolation/ruleviolation.lua | 142 ++++++++++++++++++ .../game_ruleviolation/ruleviolation.otmod | 15 ++ modules/game_ruleviolation/ruleviolation.otui | 120 +++++++++++++++ modules/game_textmessage/textmessage.lua | 2 +- 8 files changed, 332 insertions(+), 15 deletions(-) create mode 100644 modules/game_ruleviolation/ruleviolation.lua create mode 100644 modules/game_ruleviolation/ruleviolation.otmod create mode 100644 modules/game_ruleviolation/ruleviolation.otui diff --git a/modules/client_terminal/terminal.lua b/modules/client_terminal/terminal.lua index c503613c..2b1db275 100644 --- a/modules/client_terminal/terminal.lua +++ b/modules/client_terminal/terminal.lua @@ -211,9 +211,11 @@ function Terminal.executeCommand(command) currentHistoryIndex = 0 -- add new command to history - table.insert(commandHistory, command) - if #commandHistory > MaxHistory then - table.remove(commandHistory, 1) + if #commandHistory == 0 or commandHistory[#commandHistory] ~= command then + table.insert(commandHistory, command) + if #commandHistory > MaxHistory then + table.remove(commandHistory, 1) + end end -- add command line diff --git a/modules/game/game.otmod b/modules/game/game.otmod index fa636f32..94b46cea 100644 --- a/modules/game/game.otmod +++ b/modules/game/game.otmod @@ -26,6 +26,7 @@ Module - game_textbooks - game_playertrade - game_questlog + - game_ruleviolation @onLoad: | importStyle 'styles/items.otui' diff --git a/modules/game/gameinterface.lua b/modules/game/gameinterface.lua index a656a7d7..513d9a73 100644 --- a/modules/game/gameinterface.lua +++ b/modules/game/gameinterface.lua @@ -266,6 +266,11 @@ function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatu end end + if RuleViolation.hasWindowAccess() then + menu:addSeparator() + menu:addOption(tr('Rule Violation'), function() RuleViolation.show(creatureThing:getName()) end) + end + menu:addSeparator() menu:addOption(tr('Copy Name'), function() g_window.setClipboardText(creatureThing:getName()) end) diff --git a/modules/game_console/console.lua b/modules/game_console/console.lua index c0ddccad..c3f0de8d 100644 --- a/modules/game_console/console.lua +++ b/modules/game_console/console.lua @@ -89,7 +89,7 @@ local function onCreatureSpeak(name, level, speaktype, message, channelId, creat message = applyMessagePrefixies(name, level, message) if speaktype.private then - Console.addPrivateText(message, speaktype, name, false) + Console.addPrivateText(message, speaktype, name, false, name) else local channel = tr('Default') if not defaultMessage then @@ -97,7 +97,7 @@ local function onCreatureSpeak(name, level, speaktype, message, channelId, creat end if channel then - Console.addText(message, speaktype, channel) + Console.addText(message, speaktype, channel, name) elseif channelId ~= 0 then -- server sent a message on a channel that is not open warning('message in channel id ' .. channelId .. ' which is unknown, this is a server bug, relogin if you want to see messages in this channel') @@ -334,7 +334,7 @@ function Console.addChannel(name, id) return tab end -function Console.addPrivateText(text, speaktype, name, isPrivateCommand) +function Console.addPrivateText(text, speaktype, name, isPrivateCommand, creatureName) local focus = false if speaktype.speakType == SpeakPrivateNpcToPlayer then name = 'NPCs' @@ -352,17 +352,17 @@ function Console.addPrivateText(text, speaktype, name, isPrivateCommand) elseif focus then consoleTabBar:selectTab(privateTab) end - Console.addTabText(text, speaktype, privateTab) + Console.addTabText(text, speaktype, privateTab, creatureName) end -function Console.addText(text, speaktype, tabName) +function Console.addText(text, speaktype, tabName, creatureName) local tab = Console.getTab(tabName) if tab ~= nil then - Console.addTabText(text, speaktype, tab) + Console.addTabText(text, speaktype, tab, creatureName) end end -function Console.addTabText(text, speaktype, tab) +function Console.addTabText(text, speaktype, tab, creatureName) if Options.getOption('showTimestampsInConsole') then text = os.date('%H:%M') .. ' ' .. text end @@ -375,11 +375,41 @@ function Console.addTabText(text, speaktype, tab) label:setColor(speaktype.color) consoleTabBar:blinkTab(tab) + label.onMouseRelease = function (self, mousePos, mouseButton) Console.popupMenu(mousePos, mouseButton, creatureName, text) end + if consoleBuffer:getChildCount() > MAX_LINES then consoleBuffer:getFirstChild():destroy() end end +function Console.popupMenu(mousePos, mouseButton, creatureName, text) + if mouseButton == MouseRightButton then + local menu = createWidget('PopupMenu') + if creatureName then + if creatureName ~= g_game.getLocalPlayer():getName() then + menu:addOption(tr('Message to ' .. creatureName), function () g_game.openPrivateChannel(creatureName) end) + menu:addOption(tr('Add to VIP list'), function () g_game.addVip(creatureName) end) --TODO not show if creature already in vip + -- TODO ignore creatureName + menu:addSeparator() + end + --TODO select all + menu:addOption(tr('Copy message'), function () g_window.setClipboardText(text) end) + + if RuleViolation.hasWindowAccess() then + menu:addSeparator() + menu:addOption(tr('Rule Violation'), function() RuleViolation.show(creatureName, text:match('.+%:%s(.+)')) end) + end + + menu:addSeparator() + menu:addOption(tr('Copy name'), function () g_window.setClipboardText(creatureName) end) + else + --TODO select all + menu:addOption(tr('Copy message'), function () g_window.setClipboardText(text) end) + end + menu:display(mousePos) + end +end + function Console.sendCurrentMessage() local message = consoleTextEdit:getText() if #message == 0 then return end @@ -419,9 +449,11 @@ function Console.sendCurrentMessage() -- add new command to history currentMessageIndex = 0 - table.insert(messageHistory, originalMessage) - if #messageHistory > MAX_HISTORY then - table.remove(messageHistory, 1) + if #messageHistory == 0 or messageHistory[#messageHistory] ~= originalMessage then + table.insert(messageHistory, originalMessage) + if #messageHistory > MAX_HISTORY then + table.remove(messageHistory, 1) + end end -- when talking on server log, the message goes to default channel @@ -460,7 +492,7 @@ function Console.sendCurrentMessage() g_game.talkPrivate(speaktype.speakType, name, message) message = applyMessagePrefixies(player:getName(), player:getLevel(), message) - Console.addPrivateText(message, speaktype, name, isPrivateCommand) + Console.addPrivateText(message, speaktype, name, isPrivateCommand, g_game:getLocalPlayer():getName()) end end diff --git a/modules/game_ruleviolation/ruleviolation.lua b/modules/game_ruleviolation/ruleviolation.lua new file mode 100644 index 00000000..d20b6ca8 --- /dev/null +++ b/modules/game_ruleviolation/ruleviolation.lua @@ -0,0 +1,142 @@ +RuleViolation = {} + +-- private variables +local rvreasons = {} +rvreasons[0] = tr("1a) Offensive Name") +rvreasons[1] = tr("1b) Invalid Name Format") +rvreasons[2] = tr("1c) Unsuitable Name") +rvreasons[3] = tr("1d) Name Inciting Rule Violation") +rvreasons[4] = tr("2a) Offensive Statement") +rvreasons[5] = tr("2b) Spamming") +rvreasons[6] = tr("2c) Illegal Advertising") +rvreasons[7] = tr("2d) Off-Topic Public Statement") +rvreasons[8] = tr("2e) Non-English Public Statement") +rvreasons[9] = tr("2f) Inciting Rule Violation") +rvreasons[10] = tr("3a) Bug Abuse") +rvreasons[11] = tr("3b) Game Weakness Abuse") +rvreasons[12] = tr("3c) Using Unofficial Software to Play") +rvreasons[13] = tr("3d) Hacking") +rvreasons[14] = tr("3e) Multi-Clienting") +rvreasons[15] = tr("3f) Account Trading or Sharing") +rvreasons[16] = tr("4a) Threatening Gamemaster") +rvreasons[17] = tr("4b) Pretending to Have Influence on Rule Enforcement") +rvreasons[18] = tr("4c) False Report to Gamemaster") +rvreasons[19] = tr("Destructive Behaviour") +rvreasons[20] = tr("Excessive Unjustified Player Killing") + +local rvactions = {} +rvactions[0] = tr("Notation") +rvactions[1] = tr("Name Report") +rvactions[2] = tr("Banishment") +rvactions[3] = tr("Name Report + Banishment") +rvactions[4] = tr("Banishment + Final Warning") +rvactions[5] = tr("Name Report + Banishment + Final Warning") +rvactions[6] = tr("Statement Report") + +local ruleViolationWindow +local reasonsTextList +local actionsTextList + +-- public functions +function RuleViolation.hasWindowAccess() + return reasonsTextList:getChildCount() > 0 +end + +function RuleViolation.loadReasons() + reasonsTextList:destroyChildren() + + local actions = g_game.getGMActions() + for reason, actionFlags in pairs(actions) do + local label = createWidget('RVListLabel', reasonsTextList) + label:setText(rvreasons[reason]) + label.reasonId = reason + label.actionFlags = actionFlags + end + + if not RuleViolation.hasWindowAccess() and ruleViolationWindow:isVisible() then RuleViolation.hide() end +end + +function RuleViolation.init() + connect(g_game, { onLogin = RuleViolation.loadReasons }) + + ruleViolationWindow = displayUI('ruleviolation.otui') + ruleViolationWindow:setVisible(false) + + reasonsTextList = ruleViolationWindow:getChildById('reasonList') + actionsTextList = ruleViolationWindow:getChildById('actionList') + + Keyboard.bindKeyDown('Ctrl+Y', RuleViolation.show) + + if g_game.isOnline() then + RuleViolation.loadReasons() + end +end + +function RuleViolation.terminate() + disconnect(g_game, { onLogin = RuleViolation.loadReasons }) + + ruleViolationWindow:destroy() + ruleViolationWindow = nil + + reasonsTextList = nil + actionsTextList = nil +end + +function RuleViolation.show(target, statement) + if g_game.isOnline() and RuleViolation.hasWindowAccess() then + if target then + ruleViolationWindow:getChildById('nameText'):setText(target) + end + + if statement then + ruleViolationWindow:getChildById('statementText'):setText(statement) + end + + ruleViolationWindow:show() + ruleViolationWindow:raise() + end +end + +function RuleViolation.hide() + ruleViolationWindow:hide() + RuleViolation.clearForm() +end + +function RuleViolation.onSelectReason(reasonLabel, focused) + if reasonLabel.actionFlags and focused then + actionsTextList:destroyChildren() + for actionBaseFlag = 0, #rvactions do + actionFlagString = rvactions[actionBaseFlag] + if bit32.band(reasonLabel.actionFlags, math.pow(2, actionBaseFlag)) > 0 then + local label = createWidget('RVListLabel', actionsTextList) + label:setText(actionFlagString) + label.actionId = actionBaseFlag + end + end + end +end + +function RuleViolation.report() + local target = ruleViolationWindow:getChildById('nameText'):getText() + local reason = reasonsTextList:getFocusedChild().reasonId + local action = actionsTextList:getFocusedChild().actionId + local comment = ruleViolationWindow:getChildById('commentText'):getText() + local statement = ruleViolationWindow:getChildById('statementText'):getText() + local statementId = 0 -- TODO: message unique id ? + local ipBanishment = ruleViolationWindow:getChildById('ipBanCheckBox'):isChecked() + if action == 6 and statement == "" then + displayErrorBox(tr("Error"), tr("No statement has been selected.")) + elseif comment == "" then + displayErrorBox(tr("Error"), tr("You must enter a comment.")) + else + g_game.reportRuleVilation(target, reason, action, comment, statement, statementId, ipBanishment) + RuleViolation.hide() + end +end + +function RuleViolation.clearForm() + ruleViolationWindow:getChildById('nameText'):clearText() + ruleViolationWindow:getChildById('commentText'):clearText() + ruleViolationWindow:getChildById('statementText'):clearText() + ruleViolationWindow:getChildById('ipBanCheckBox'):setChecked(false) +end \ No newline at end of file diff --git a/modules/game_ruleviolation/ruleviolation.otmod b/modules/game_ruleviolation/ruleviolation.otmod new file mode 100644 index 00000000..33d976bf --- /dev/null +++ b/modules/game_ruleviolation/ruleviolation.otmod @@ -0,0 +1,15 @@ +Module + name: game_ruleviolation + description: Rule violation interface + author: OTClient team + website: https://github.com/edubart/otclient + + dependencies: + - game + + @onLoad: | + dofile 'ruleviolation' + RuleViolation.init() + + @onUnload: | + RuleViolation.terminate() diff --git a/modules/game_ruleviolation/ruleviolation.otui b/modules/game_ruleviolation/ruleviolation.otui new file mode 100644 index 00000000..129aba53 --- /dev/null +++ b/modules/game_ruleviolation/ruleviolation.otui @@ -0,0 +1,120 @@ +RVListLabel < Label + background-color: alpha + text-offset: 2 0 + focusable: true + @onFocusChange: function (self, focused) RuleViolation.onSelectReason(self, focused) end + + $focus: + background-color: #ffffff22 + color: #ffffff + +RVLabel < Label + anchors.left: parent.left + anchors.right: parent.right + + $first: + anchors.top: parent.top + + $!first: + margin-top: 10 + anchors.top: prev.bottom + +RVTextEdit < TextEdit + margin-top: 2 + anchors.left: parent.left + anchors.right: parent.right + + $first: + anchors.top: parent.top + + $!first: + anchors.top: prev.bottom + +MainWindow + id: ruleViolationWindow + size: 400 445 + text: Rule Violation + + RVLabel + !text: tr('Name:') + + RVTextEdit + id: nameText + + RVLabel + !text: tr('Statement:') + + RVTextEdit + id: statementText + enabled: false + + RVLabel + !text: tr('Reason:') + + TextList + id: reasonList + height: 100 + anchors.top: prev.bottom + anchors.left: parent.left + anchors.right: parent.right + margin-top: 2 + focusable: false + vertical-scrollbar: reasonListScrollBar + + VerticalScrollBar + id: reasonListScrollBar + anchors.top: reasonList.top + anchors.bottom: reasonList.bottom + anchors.right: reasonList.right + step: 14 + pixels-scroll: true + + RVLabel + !text: tr('Action:') + + TextList + id: actionList + height: 60 + anchors.top: prev.bottom + anchors.left: parent.left + anchors.right: parent.right + margin-top: 2 + focusable: false + vertical-scrollbar: actionListScrollBar + + VerticalScrollBar + id: actionListScrollBar + anchors.top: actionList.top + anchors.bottom: actionList.bottom + anchors.right: actionList.right + step: 14 + pixels-scroll: true + + CheckBox + id: ipBanCheckBox + !text: tr('IP Address Banishment') + margin-top: 10 + anchors.top: prev.bottom + anchors.left: parent.left + anchors.right: parent.right + + RVLabel + !text: tr('Comment:') + + RVTextEdit + id: commentText + + Button + !text: tr('Cancel') + width: 64 + anchors.right: parent.right + anchors.bottom: parent.bottom + @onClick: RuleViolation.hide() + + Button + !text: tr('Ok') + width: 64 + margin-right: 5 + anchors.right: prev.left + anchors.bottom: parent.bottom + @onClick: RuleViolation.report() \ No newline at end of file diff --git a/modules/game_textmessage/textmessage.lua b/modules/game_textmessage/textmessage.lua index 79b0a201..f9ca13c9 100644 --- a/modules/game_textmessage/textmessage.lua +++ b/modules/game_textmessage/textmessage.lua @@ -29,7 +29,7 @@ local function displayMessage(msgtype, msg, time) end end - if msgtype.labelId then + if msgtype.labelId then local label = GameInterface.getMapPanel():recursiveGetChildById(msgtype.labelId) label:setText(msg)