chat: Implement staff chat(s) using staff channels.
This was so much fun to write! Also, it doesn't matter if a hacked client sends a different chatMode, because only staff will see it and they can take action accordingly. The message prefixing was only a temporary solution to let the other staff members know that they are talking in a staff chat mode. Perhaps in the future, this should use different chat bubble colours.
This commit is contained in:
parent
302d0daa32
commit
57049d3192
3 changed files with 48 additions and 7 deletions
|
@ -285,7 +285,7 @@ dclass OtpAvatarManager : DistributedObject {
|
|||
|
||||
dclass ChatAgent : DistributedObject {
|
||||
adminChat(uint32 aboutId, string message);
|
||||
chatMessage(string(0-256) message) clsend;
|
||||
chatMessage(string(0-256) message, uint8 chatMode) clsend;
|
||||
whisperMessage(uint32 receiverAvId, string(0-256) message) clsend;
|
||||
sfWhisperMessage(uint32 receiverAvId, string(0-256) message) clsend;
|
||||
};
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
from direct.distributed.DistributedObjectGlobal import DistributedObjectGlobal
|
||||
from pandac.PandaModules import *
|
||||
from otp.otpbase import OTPGlobals
|
||||
from otp.ai.MagicWordGlobal import *
|
||||
|
||||
class ChatAgent(DistributedObjectGlobal):
|
||||
def __init__(self, cr):
|
||||
DistributedObjectGlobal.__init__(self, cr)
|
||||
self.chatMode = 0
|
||||
|
||||
def delete(self):
|
||||
self.ignoreAll()
|
||||
self.cr.chatManager = None
|
||||
self.cr.chatAgent = None
|
||||
DistributedObjectGlobal.delete(self)
|
||||
return
|
||||
|
||||
|
@ -17,10 +20,35 @@ class ChatAgent(DistributedObjectGlobal):
|
|||
messenger.send('adminChat', [aboutId, message])
|
||||
|
||||
def sendChatMessage(self, message):
|
||||
self.sendUpdate('chatMessage', [message])
|
||||
self.sendUpdate('chatMessage', [message, self.chatMode])
|
||||
|
||||
def sendWhisperMessage(self, receiverAvId, message):
|
||||
self.sendUpdate('whisperMessage', [receiverAvId, message])
|
||||
|
||||
def sendSFWhisperMessage(self, receiverAvId, message):
|
||||
self.sendUpdate('sfWhisperMessage', [receiverAvId, message])
|
||||
|
||||
@magicWord(category=CATEGORY_MODERATION, types=[int])
|
||||
def chatmode(mode=-1):
|
||||
""" Set the chat mode of the current avatar. """
|
||||
mode2name = {
|
||||
0 : "user",
|
||||
1 : "moderator",
|
||||
2 : "administrator",
|
||||
3 : "system administrator",
|
||||
}
|
||||
if base.cr.chatAgent is None:
|
||||
return "No ChatAgent found."
|
||||
if mode == -1:
|
||||
return "You are currently talking in the %s chat mode." % mode2name.get(base.cr.chatAgent.chatMode, "N/A")
|
||||
if not 0 <= mode <= 3:
|
||||
return "Invalid chat mode specified."
|
||||
if mode == 3 and spellbook.getInvoker().getAdminAccess() < 500:
|
||||
return "Chat mode 3 is reserved for system administrators."
|
||||
if mode == 2 and spellbook.getInvoker().getAdminAccess() < 400:
|
||||
return "Chat mode 2 is reserved for administrators."
|
||||
if mode == 1 and spellbook.getInvoker().getAdminAccess() < 200:
|
||||
# Like this will ever happen, but whatever.
|
||||
return "Chat mode 1 is reserved for moderators."
|
||||
base.cr.chatAgent.chatMode = mode
|
||||
return "You are now talking in the %s chat mode." % mode2name.get(mode, "N/A")
|
||||
|
|
|
@ -2,6 +2,7 @@ from direct.directnotify import DirectNotifyGlobal
|
|||
from direct.distributed.DistributedObjectGlobalUD import DistributedObjectGlobalUD
|
||||
# TODO: OTP should not depend on Toontown... Hrrm.
|
||||
from toontown.chat.TTWhiteList import TTWhiteList
|
||||
from otp.distributed import OtpDoGlobals
|
||||
|
||||
class ChatAgentUD(DistributedObjectGlobalUD):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("ChatAgentUD")
|
||||
|
@ -10,9 +11,18 @@ class ChatAgentUD(DistributedObjectGlobalUD):
|
|||
DistributedObjectGlobalUD.announceGenerate(self)
|
||||
|
||||
self.whiteList = TTWhiteList()
|
||||
|
||||
self.chatMode2channel = {
|
||||
1 : OtpDoGlobals.OTP_MOD_CHANNEL,
|
||||
2 : OtpDoGlobals.OTP_ADMIN_CHANNEL,
|
||||
3 : OtpDoGlobals.OTP_SYSADMIN_CHANNEL,
|
||||
}
|
||||
self.chatMode2prefix = {
|
||||
1 : "[MOD] ",
|
||||
2 : "[ADMIN] ",
|
||||
3 : "[SYSADMIN] ",
|
||||
}
|
||||
# Open chat
|
||||
def chatMessage(self, message):
|
||||
def chatMessage(self, message, chatMode):
|
||||
sender = self.air.getAvatarIdFromSender()
|
||||
if sender == 0:
|
||||
self.air.writeServerEvent('suspicious', accId=self.air.getAccountIdFromSender(),
|
||||
|
@ -25,8 +35,11 @@ class ChatAgentUD(DistributedObjectGlobalUD):
|
|||
|
||||
# TODO: The above is probably a little too ugly for my taste... Maybe AIR
|
||||
# should be given an API for sending updates for unknown objects?
|
||||
if chatMode != 0:
|
||||
# Staff messages do not need to be cleaned. [TODO: Blacklist this?]
|
||||
cleanMessage = self.chatMode2prefix.get(chatMode, "") + message
|
||||
DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD']
|
||||
dg = DistributedAvatar.aiFormatUpdate('setTalk', sender, sender,
|
||||
dg = DistributedAvatar.aiFormatUpdate('setTalk', sender, self.chatMode2channel.get(chatMode, sender),
|
||||
self.air.ourChannel,
|
||||
[0, 0, '', cleanMessage, modifications, 0])
|
||||
self.air.send(dg)
|
||||
|
@ -44,7 +57,7 @@ class ChatAgentUD(DistributedObjectGlobalUD):
|
|||
# Maybe a better "cleaner" way of doing this, but it works
|
||||
self.air.writeServerEvent('whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage)
|
||||
DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD']
|
||||
dg = DistributedAvatar.aiFormatUpdate('setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel,
|
||||
dg = DistributedAvatar.aiFormatUpdate('setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel,
|
||||
[sender, sender, '', cleanMessage, modifications, 0])
|
||||
self.air.send(dg)
|
||||
|
||||
|
@ -60,7 +73,7 @@ class ChatAgentUD(DistributedObjectGlobalUD):
|
|||
|
||||
self.air.writeServerEvent('sf-whisper-said', avId=sender, reciever=receiverAvId, msg=message, cleanMsg=cleanMessage)
|
||||
DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD']
|
||||
dg = DistributedAvatar.aiFormatUpdate('setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel,
|
||||
dg = DistributedAvatar.aiFormatUpdate('setTalkWhisper', receiverAvId, receiverAvId, self.air.ourChannel,
|
||||
[sender, sender, '', cleanMessage, [], 0])
|
||||
self.air.send(dg)
|
||||
|
||||
|
|
Loading…
Reference in a new issue