Multiprotocol 8.1-9.6 finally working

Still have many minor issues, tests are needed
No recompilation needed anymore
9.60 messages is not fully implemented
This commit is contained in:
Eduardo Bart
2012-07-26 06:12:20 -03:00
parent 98c279c10b
commit 36c029fc69
28 changed files with 575 additions and 511 deletions

View File

@@ -5,7 +5,7 @@ function Client.reloadScripts()
dofile '/otclientrc'
local message = tr('All modules and scripts were reloaded.')
modules.game_textmessage.displayEventAdvance(message)
modules.game_textmessage.displayGameMessage(message)
print(message)
end

View File

@@ -171,28 +171,6 @@ KeyNumpad7 = 148
KeyNumpad8 = 149
KeyNumpad9 = 150
SpeakSay = 1
SpeakWhisper = 2
SpeakYell = 3
SpeakBroadcast = 4
SpeakPrivate = 5
SpeakPrivateRed = 6
SpeakPrivatePlayerToNpc = 7
SpeakPrivateNpcToPlayer = 8
SpeakChannelYellow = 9
SpeakChannelWhite = 10
SpeakChannelRed = 11
SpeakChannelOrange = 12
SpeakMonsterSay = 13
SpeakMonsterYell = 14
FightOffensive = 1
FightBalanced = 2
FightDefensive = 3
DontChase = 0
ChaseOpponent = 1
ExtendedActivate = 0
ExtendedLocales = 1
ExtendedParticles = 2

View File

@@ -32,6 +32,7 @@ table.insert(LifeBarColors, {percentAbove = 3, color = '#3C0000' } )
table.insert(LifeBarColors, {percentAbove = -1, color = '#4F0000' } )
function init()
g_ui.importStyle('battlebutton.otui')
battleWindow = g_ui.loadUI('battle.otui', modules.game_interface.getRightPanel())
battleButton = TopMenu.addRightGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', toggle)
battleButton:setOn(true)
@@ -173,10 +174,12 @@ function addCreature(creature)
local creatureId = creature:getId()
if battleButtonsByCreaturesList[creatureId] == nil then
local battleButton = g_ui.loadUI('battlebutton.otui', battlePanel)
local battleButton = g_ui.createWidget('BattleButton', battlePanel)
local creatureWidget = battleButton:getChildById('creature')
local labelWidget = battleButton:getChildById('label')
local lifeBarWidget = battleButton:getChildById('lifeBar')
battleButton.onHoverChange = onbattleButtonHoverChange
battleButton.onMouseRelease = onMouseRelease
battleButton:setId('BattleButton_' .. creature:getName():gsub('%s','_'))
battleButton.creatureId = creatureId

View File

@@ -1,11 +1,7 @@
BattleButton < UIButton
BattleButton
height: 20
margin-top: 5
fixed-size: true
&onHoverChange: onbattleButtonHoverChange
&onMouseRelease: onMouseRelease
&isBattleButton: true
UICreature

View File

@@ -22,7 +22,7 @@ end
function doReport()
g_game.reportBug(bugTextEdit:getText())
bugReportWindow:hide()
modules.game_textmessage.displayEventAdvance(tr('Bug report sent.'))
modules.game_textmessage.displayGameMessage(tr('Bug report sent.'))
end
function show()

View File

@@ -1,36 +1,36 @@
SpeakTypesSettings = {
say = { speakType = SpeakSay, color = '#FFFF00' },
whisper = { speakType = SpeakWhisper, color = '#FFFF00' },
yell = { speakType = SpeakYell, color = '#FFFF00' },
broadcast = { speakType = SpeakBroadcast, color = '#F55E5E' },
private = { speakType = SpeakPrivate, color = '#5FF7F7', private = true },
privateRed = { speakType = SpeakPrivateRed, color = '#F55E5E', private = true },
privatePlayerToPlayer = { speakType = SpeakPrivate, color = '#9F9DFD', private = true },
privatePlayerToNpc = { speakType = SpeakPrivatePlayerToNpc, color = '#9F9DFD', private = true, npcChat = true },
privateNpcToPlayer = { speakType = SpeakPrivateNpcToPlayer, color = '#5FF7F7', private = true, npcChat = true },
channelYellow = { speakType = SpeakChannelYellow, color = '#FFFF00' },
channelWhite = { speakType = SpeakChannelWhite, color = '#FFFFFF' },
channelRed = { speakType = SpeakChannelRed, color = '#F55E5E' },
channelOrange = { speakType = SpeakChannelOrange, color = '#FE6500' },
monsterSay = { speakType = SpeakMonsterSay, color = '#FE6500', hideInConsole = true},
monsterYell = { speakType = SpeakMonsterYell, color = '#FE6500', hideInConsole = true},
say = { speakType = MessageModes.Say, color = '#FFFF00' },
whisper = { speakType = MessageModes.Whisper, color = '#FFFF00' },
yell = { speakType = MessageModes.Yell, color = '#FFFF00' },
broadcast = { speakType = MessageModes.GamemasterPrivateFrom, color = '#F55E5E' },
private = { speakType = MessageModes.PrivateTo, color = '#5FF7F7', private = true },
privateRed = { speakType = MessageModes.GamemasterTo, color = '#F55E5E', private = true },
privatePlayerToPlayer = { speakType = MessageModes.PrivateTo, color = '#9F9DFD', private = true },
privatePlayerToNpc = { speakType = MessageModes.NpcTo, color = '#9F9DFD', private = true, npcChat = true },
privateNpcToPlayer = { speakType = MessageModes.NpcFrom, color = '#5FF7F7', private = true, npcChat = true },
channelYellow = { speakType = MessageModes.Channel, color = '#FFFF00' },
channelWhite = { speakType = MessageModes.ChannelManagement, color = '#FFFFFF' },
channelRed = { speakType = MessageModes.GamemasterChannel, color = '#F55E5E' },
channelOrange = { speakType = MessageModes.ChannelHighlight, color = '#FE6500' },
monsterSay = { speakType = MessageModes.MonsterSay, color = '#FE6500', hideInConsole = true},
monsterYell = { speakType = MessageModes.MonsterYell, color = '#FE6500', hideInConsole = true},
}
SpeakTypes = {
[SpeakSay] = SpeakTypesSettings.say,
[SpeakWhisper] = SpeakTypesSettings.whisper,
[SpeakYell] = SpeakTypesSettings.yell,
[SpeakBroadcast] = SpeakTypesSettings.broadcast,
[SpeakPrivate] = SpeakTypesSettings.private,
[SpeakPrivateRed] = SpeakTypesSettings.privateRed,
[SpeakPrivatePlayerToNpc] = SpeakTypesSettings.privatePlayerToNpc,
[SpeakPrivateNpcToPlayer] = SpeakTypesSettings.privateNpcToPlayer,
[SpeakChannelYellow] = SpeakTypesSettings.channelYellow,
[SpeakChannelWhite] = SpeakTypesSettings.channelWhite,
[SpeakChannelRed] = SpeakTypesSettings.channelRed,
[SpeakChannelOrange] = SpeakTypesSettings.channelOrange,
[SpeakMonsterSay] = SpeakTypesSettings.monsterSay,
[SpeakMonsterYell] = SpeakTypesSettings.monsterYell,
[MessageModes.Say] = SpeakTypesSettings.say,
[MessageModes.Whisper] = SpeakTypesSettings.whisper,
[MessageModes.Yell] = SpeakTypesSettings.yell,
[MessageModes.GamemasterPrivateFrom] = SpeakTypesSettings.broadcast,
[MessageModes.PrivateFrom] = SpeakTypesSettings.private,
[MessageModes.GamemasterPrivateFrom] = SpeakTypesSettings.privateRed,
[MessageModes.NpcTo] = SpeakTypesSettings.privatePlayerToNpc,
[MessageModes.NpcFrom] = SpeakTypesSettings.privateNpcToPlayer,
[MessageModes.Channel] = SpeakTypesSettings.channelYellow,
[MessageModes.ChannelManagement] = SpeakTypesSettings.channelWhite,
[MessageModes.GamemasterChannel] = SpeakTypesSettings.channelRed,
[MessageModes.ChannelHighlight] = SpeakTypesSettings.channelOrange,
[MessageModes.MonsterSay] = SpeakTypesSettings.monsterSay,
[MessageModes.MonsterYell] = SpeakTypesSettings.monsterYell,
}
SayModes = {
@@ -56,7 +56,7 @@ ignoreNpcMessages = false
function init()
connect(g_game, { onCreatureSpeak = onCreatureSpeak,
connect(g_game, { onTalk = onTalk,
onChannelList = onChannelList,
onOpenChannel = onOpenChannel,
onOpenPrivateChannel = onOpenPrivateChannel,
@@ -94,7 +94,7 @@ function init()
end
function terminate()
disconnect(g_game, { onCreatureSpeak = onCreatureSpeak,
disconnect(g_game, { onTalk = onTalk,
onChannelList = onChannelList,
onOpenChannel = onOpenChannel,
onOpenPrivateChannel = onOpenPrivateChannel,
@@ -239,7 +239,7 @@ end
function addPrivateText(text, speaktype, name, isPrivateCommand, creatureName)
local focus = false
if speaktype.speakType == SpeakPrivateNpcToPlayer then
if speaktype.speakType == SpeakNpcFrom then
name = 'NPCs'
focus = true
end
@@ -301,9 +301,9 @@ function popupMenu(mousePos, mouseButton, creatureName, text)
--TODO select all
menu:addOption(tr('Copy message'), function () g_window.setClipboardText(text) end)
if RuleViolation.hasWindowAccess() then
if modules.game_ruleviolation.hasWindowAccess() then
menu:addSeparator()
menu:addOption(tr('Rule Violation'), function() RuleViolation.show(creatureName, text:match('.+%:%s(.+)')) end)
menu:addOption(tr('Rule Violation'), function() modules.game_ruleviolation.show(creatureName, text:match('.+%:%s(.+)')) end)
end
menu:addSeparator()
@@ -448,8 +448,8 @@ function applyMessagePrefixies(name, level, message)
return message
end
function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos)
if ignoreNpcMessages and speaktype == SpeakPrivateNpcToPlayer then return end
function onTalk(name, level, speaktype, message, channelId, creaturePos)
if ignoreNpcMessages and speaktype == SpeakNpcFrom then return end
local defaultMessage = speaktype < 3 and true or false
speaktype = SpeakTypes[speaktype]
if speaktype.hideInConsole then return end
@@ -458,11 +458,6 @@ function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos
if speaktype.private then
addPrivateText(composedMessage, speaktype, name, false, name)
if Options.getOption('showPrivateMessagesOnScreen') then
if(speaktype.speakType ~= SpeakPrivateNpcToPlayer) then
TextMessage.displayPrivate(name .. ':\n' .. message)
end
end
else
local channel = tr('Default')
if not defaultMessage then

View File

@@ -347,9 +347,9 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
end
end
if RuleViolation.hasWindowAccess() then
if modules.game_ruleviolation.hasWindowAccess() then
menu:addSeparator()
menu:addOption(tr('Rule Violation'), function() RuleViolation.show(creatureThing:getName()) end)
menu:addOption(tr('Rule Violation'), function() modules.game_ruleviolation.show(creatureThing:getName()) end)
end
menu:addSeparator()
@@ -430,7 +430,7 @@ function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, u
if autoWalkPos and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseLeftButton then
local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), autoWalkPos, 127)
if #dirs == 0 then
modules.game_textmessage.displayStatus(tr('There is no way.'))
modules.game_textmessage.displayStatusMessage(tr('There is no way.'))
return true
end
g_game.autoWalk(dirs)

View File

@@ -146,7 +146,7 @@ function onMinimapMouseRelease(self, mousePosition, mouseButton)
if tile and mouseButton == MouseLeftButton and self:isPressed() then
local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), tile:getPosition(), 127)
if #dirs == 0 then
modules.game_textmessage.displayStatus(tr('There is no way.'))
modules.game_textmessage.displayStatusMessage(tr('There is no way.'))
return true
end
g_game.autoWalk(dirs)

View File

@@ -32,7 +32,7 @@ function displayDeadMessage()
return
end
modules.game_textmessage.displayEventAdvance(tr('You are dead.'))
modules.game_textmessage.displayGameMessage(tr('You are dead.'))
end
function openWindow()

View File

@@ -1,60 +0,0 @@
function getMessageTypes(version)
if version >= 960 then
perror("TODO: message types for 9.6")
return {}
elseif version >= 861 then
return {
[13] = 'ConsoleOrange',
[14] = 'ConsoleOrange',
[15] = 'Warning',
[16] = 'EventAdvance',
[17] = 'EventDefault',
[18] = 'StatusDefault',
[19] = 'Info',
[20] = 'StatusSmall',
[21] = 'ConsoleBlue',
[22] = 'ConsoleRed'
}
elseif version >= 854 then
return {
[18] = 'ConsoleRed',
[19] = 'ConsoleOrange',
[20] = 'ConsoleOrange',
[21] = 'Warning',
[22] = 'EventAdvance',
[23] = 'EventDefault',
[24] = 'StatusDefault',
[25] = 'Info',
[26] = 'StatusSmall',
[27] = 'ConsoleBlue'
}
else
return {
[18] = 'Warning',
[19] = 'EventAdvance',
[20] = 'EventDefault',
[21] = 'StatusDefault',
[22] = 'Info',
[23] = 'StatusSmall',
[24] = 'ConsoleBlue',
[25] = 'ConsoleRed',
[26] = 'ConsoleOrange',
[27] = 'ConsoleOrange',
}
end
end
function parseTextMessage(msg)
local msgtype = msg:getU8()
local text = msg:getString()
msgtype = getMessageTypes(g_game.getClientVersion())[msgtype]
signalcall(g_game.onTextMessage, msgtype, text)
end
function registerProtocol()
ProtocolGame.registerOpcode(GameServerOpcodes.GameServerTextMessage, parseTextMessage)
end
function unregisterProtocol()
ProtocolGame.unregisterOpcode(GameServerOpcodes.GameServerTextMessage)
end

View File

@@ -1,115 +1,96 @@
MessageTypes = {
ConsoleRed = { color = '#F55E5E', consoleTab = tr('Default') },
ConsoleOrange = { color = '#FE6500', consoleTab = tr('Default') },
ConsoleBlue = { color = '#9F9DFD', consoleTab = tr('Default') },
Warning = { color = '#F55E5E', consoleTab = tr('Server Log'), labelId = 'warningLabel' },
Info = { color = '#00EB00', consoleTab = tr('Server Log'), labelId = 'infoLabel', consoleOption = 'showInfoMessagesInConsole' },
EventAdvance = { color = '#FFFFFF', consoleTab = tr('Server Log'), labelId = 'advanceLabel', consoleOption = 'showEventMessagesInConsole' },
EventDefault = { color = '#FFFFFF', consoleTab = tr('Server Log'), labelId = 'statusLabel', consoleOption = 'showEventMessagesInConsole' },
StatusDefault = { color = '#FFFFFF', consoleTab = tr('Server Log'), labelId = 'statusLabel', consoleOption = 'showStatusMessagesInConsole' },
StatusSmall = { color = '#FFFFFF', labelId = 'statusLabel' },
Private = { color = '#5FF7F7', labelId = 'privateLabel' }
MessageSettings = {
consoleRed = { color = TextColors.red, consoleTab='Default' },
consoleOrange = { color = TextColors.orange, consoleTab='Default' },
consoleBlue = { color = TextColors.blue, consoleTab='Default' },
centerRed = { color = TextColors.red, consoleTab='Server Log', screenTarget='lowCenterLabel' },
centerGreen = { color = TextColors.green, consoleTab='Server Log', screenTarget='highCenterLabel', consoleOption='showInfoMessagesInConsole' },
centerWhite = { color = TextColors.white, consoleTab='Server Log', screenTarget='middleCenterLabel', consoleOption='showEventMessagesInConsole' },
bottomWhite = { color = TextColors.white, consoleTab='Server Log', screenTarget='statusLabel', consoleOption='showEventMessagesInConsole' },
status = { color = TextColors.white, consoleTab='Server Log', screenTarget='statusLabel', consoleOption='showStatusMessagesInConsole' },
statusSmall = { color = TextColors.white, screenTarget='statusLabel' },
private = { color = TextColors.lightblue, screenTarget='privateLabel' }
}
centerTextMessagePanel = nil
statusLabel = nil
privateLabel = nil
warningLabel = nil
advanceLabel = nil
infoLabel = nil
MessageTypes = {
[MessageModes.MonsterSay] = MessageSettings.orange,
[MessageModes.MonsterYell] = MessageSettings.orange,
[MessageModes.Failure] = MessageSettings.statusSmall,
[MessageModes.Login] = MessageSettings.bottomWhite,
[MessageModes.Game] = MessageSettings.centerWhite,
[MessageModes.Status] = MessageSettings.status,
[MessageModes.Warning] = MessageSettings.centerRed,
[MessageModes.Look] = MessageSettings.centerGreen,
[MessageModes.Loot] = MessageSettings.centerGreen,
[MessageModes.Red] = MessageSettings.consoleRed,
[MessageModes.Blue] = MessageSettings.consoleBlue,
[MessageModes.PrivateFrom] = MessageSettings.private
}
messagesPanel = nil
function init()
connect(g_game, {
onTextMessage = displayMessage,
onGameStart = clearMessages
})
registerProtocol()
g_ui.importStyle('textmessage.otui')
centerTextMessagePanel = g_ui.createWidget('Panel', modules.game_interface.getMapPanel())
centerTextMessagePanel:setId('centerTextMessagePanel')
local layout = UIVerticalLayout.create(centerTextMessagePanel)
layout:setFitChildren(true)
centerTextMessagePanel:setLayout(layout)
centerTextMessagePanel:setWidth(360)
centerTextMessagePanel:centerIn('parent')
warningLabel = createTextMessageLabel('warningLabel', centerTextMessagePanel, 'CenterLabel')
advanceLabel = createTextMessageLabel('advanceLabel', centerTextMessagePanel, 'CenterLabel')
infoLabel = createTextMessageLabel('infoLabel', centerTextMessagePanel, 'CenterLabel')
privateLabel = createTextMessageLabel('privateLabel', modules.game_interface.getMapPanel(), 'TopCenterLabel')
statusLabel = createTextMessageLabel('statusLabel', modules.game_interface.getMapPanel(), 'BottomLabel')
connect(g_game, 'onTextMessage', displayMessage)
connect(g_game, 'onPrivateTalk', onPrivateTalk)
connect(g_game, 'onGameEnd', clearMessages)
messagesPanel = g_ui.loadUI('textmessage.otui', modules.game_interface.getRootPanel())
end
function terminate()
disconnect(g_game, {
onTextMessage = display,
onGameStart = clearMessages
})
unregisterProtocol()
disconnect(g_game, 'onTextMessage', displayMessage)
disconnect(g_game, 'onPrivateTalk', onPrivateTalk)
disconnect(g_game, 'onGameEnd',clearMessages)
clearMessages()
messagesPanel:destroy()
end
removeEvent(warningLabel.hideEvent)
removeEvent(advanceLabel.hideEvent)
removeEvent(infoLabel.hideEvent)
removeEvent(privateLabel.hideEvent)
removeEvent(statusLabel.hideEvent)
function calculateVisibleTime(text)
return math.max(#text * 100, 4000)
end
centerTextMessagePanel:destroy()
statusLabel:destroy()
privateLabel:destroy()
function displayMessage(mode, text)
if not g_game.isOnline() then return end
local msgtype = MessageTypes[mode]
if not msgtype then
perror('unhandled message mode ' .. mode)
return
end
if msgtype.consoleTab ~= nil and (msgtype.consoleOption == nil or Options.getOption(msgtype.consoleOption)) then
modules.game_console.addText(text, msgtype, tr(msgtype.consoleTab))
--TODO move to game_console
end
if msgtype.screenTarget then
local label = messagesPanel:recursiveGetChildById(msgtype.screenTarget)
label:setText(text)
label:setColor(msgtype.color)
label:setVisible(true)
removeEvent(label.hideEvent)
label.hideEvent = scheduleEvent(function() label:setVisible(false) end, calculateVisibleTime(text))
end
end
function displayStatusMessage(text)
displayMessage(MessageModes.Status, text)
end
function displayGameMessage(text)
displayMessage(MessageModes.Game, text)
end
function clearMessages()
warningLabel:hide()
advanceLabel:hide()
infoLabel:hide()
privateLabel:hide()
statusLabel:hide()
end
function createTextMessageLabel(id, parent, class)
local label = g_ui.createWidget(class, parent)
label:setFont('verdana-11px-rounded')
label:setId(id)
return label
end
function displayMessage(msgtype, msg, time)
if not g_game.isOnline() then return end
msgtype = MessageTypes[msgtype]
if msgtype.consoleTab ~= nil then
if msgtype.consoleOption == nil or Options.getOption(msgtype.consoleOption) then
modules.game_console.addText(msg, msgtype, msgtype.consoleTab)
for _i,child in pairs(messagesPanel:recursiveGetChildren()) do
if child:getId():match('Label') then
child:hide()
removeEvent(child.hideEvent)
end
end
end
if msgtype.labelId then
local label = modules.game_interface.getMapPanel():recursiveGetChildById(msgtype.labelId)
label:setText(msg)
label:setColor(msgtype.color)
if not time then
time = math.max(#msg * 100, 4000)
else
time = time * 1000
end
removeEvent(label.hideEvent)
addEvent(function() label:setVisible(true) end)
label.hideEvent = scheduleEvent(function() label:setVisible(false) end, time)
function onPrivateTalk(code, text, speaker, speakerlevel, statmentid)
if Options.getOption('showPrivateMessagesOnScreen') then
displayMessage(code, speaker .. ':\n' .. text)
end
end
function displayStatus(msg, time)
displayMessage('StatusSmall', msg)
end
function displayEventAdvance(msg, time)
displayMessage('EventAdvance', msg, time)
end
function displayPrivate(msg, time)
displayMessage('Private', time)
end

View File

@@ -4,13 +4,6 @@ Module
author: edubart
website: www.otclient.info
sandboxed: true
dependencies:
- game_interface
scripts:
- protocol.lua
- textmessage.lua
scripts: [ textmessage.lua ]
@onLoad: init()
@onUnload: terminate()
@onUnload: terminate()

View File

@@ -1,4 +1,4 @@
CenterLabel < UILabel
TextMessageLabel < UILabel
font: verdana-11px-rounded
text-align: center
text-wrap: true
@@ -6,17 +6,35 @@ CenterLabel < UILabel
margin-bottom: 2
visible: false
TopCenterLabel < UILabel
font: verdana-11px-rounded
text-align: center
text-wrap: true
visible: false
anchors.top: parent.top
anchors.bottom: centerTextMessagePanel.top
anchors.horizontalCenter: parent.horizontalCenter
width: 275
Panel
anchors.fill: gameMapPanel
focusable: false
BottomLabel < CenterLabel
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Panel
id: centerTextMessagePanel
layout:
type: verticalBox
fit-children: true
width: 360
anchors.centerIn: parent
TextMessageLabel
id: highCenterLabel
TextMessageLabel
id: middleCenterLabel
TextMessageLabel
id: lowCenterLabel
TextMessageLabel
id: privateLabel
anchors.top: parent.top
anchors.bottom: centerTextMessagePanel.top
anchors.horizontalCenter: parent.horizontalCenter
text-auto-resize: false
width: 275
TextMessageLabel
id: statusLabel
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right

View File

@@ -34,6 +34,13 @@ SouthEast = 5
SouthWest = 6
NorthWest = 7
FightOffensive = 1
FightBalanced = 2
FightDefensive = 3
DontChase = 0
ChaseOpponent = 1
GameExtendedOpcode = 0
GameProtocolChecksum = 1
GameAccountNames = 2
@@ -59,6 +66,72 @@ GameReverseCreatureStack = 21
GameMagicEffectU16 = 22
GamePlayerMarket = 23
TextColors = {
red = '#f55e5e', --'#c83200'
orange = '#f36500', --'#c87832'
yellow = '#ffff00', --'#e6c832'
green = '#00EB00', --'#3fbe32'
lightblue = '#5ff7f7',
--blue1 = '#6e50dc',
--blue2 = '#3264c8',
--blue3 = '#0096c8',
white = '#ffffff' --'#bebebe'
}
MessageModes = {
None = 0,
Say = 1,
Whisper = 2,
Yell = 3,
PrivateFrom = 4,
PrivateTo = 5,
ChannelManagement = 6,
Channel = 7,
ChannelHighlight = 8,
Spell = 9,
NpcFrom = 10,
NpcTo = 11,
GamemasterBroadcast = 12,
GamemasterChannel = 13,
GamemasterPrivateFrom = 14,
GamemasterPrivateTo = 15,
Login = 16,
Warning = 17,
Game = 18,
Failure = 19,
Look = 20,
DamageDealed = 21,
DamageReceived = 22,
Heal = 23,
Exp = 24,
DamageOthers = 25,
HealOthers = 26,
ExpOthers = 27,
Status = 28,
Loot = 29,
TradeNpc = 30,
Guild = 31,
PartyManagement = 32,
Party = 33,
BarkLow = 34,
BarkLoud = 35,
Report = 36,
HotkeyUse = 37,
TutorialHint = 38,
Thankyou = 39,
Market = 40,
BeyondLast = 41,
MonsterYell = 42,
MonsterSay = 43,
Red = 44,
Blue = 45,
RVRChannel = 46,
RVRAnswer = 47,
RVRContinue = 48,
Last = 49,
Invalid = 255
}
OTSERV_RSA = "1091201329673994292788609605089955415282375029027981291234687579" ..
"3726629149257644633073969600111060390723088861007265581882535850" ..
"3429057592827629436413108566029093628212635953836686562675849720" ..