Hierarchia
Legacy system czatu używa modelu klient-serwer. Moduł modułu czatu serwera ChatChannel i ChatSpeaker jest zarządzany przez 2>ChatService2> na serwerze, podczas gdy klient jest odpowiedzialny za wejście i wyświetlenie wiadomości. Komunikacja między serwerem a klientami jest zarządz
Sam usługa silnika Chat jest niezbędną jednostką magazynową dla systemu czatu: gdy miejsce Roblox zostanie załadowane (na przykład w klientach lub Studio podczas uruchomienia lub gry), następujące komponenty zostaną automatycznie załadowane do usługi Chat jeśli Chat.LoadDefaultChat jest prawdziwy.
- ChatModule — Ta Folder jest kolekcją modułów wymaganych przez ChatServiceRunner . Wszystkie treści tego katalogu są wymagane przez skrypt i używane do tworzenia niestandardowego zachowania na serwerze.
- ClientChatModule — Ten katalog zawiera różne ModuleScripts wymagane przez ChatScript .
- CommandModule — zawiera moduły używane do implementacji komend czatu strony klienta.
- ModuleKreatorowe — Zawiera moduły używane do przetwarzania i formatowania wiadomości.
- ChatCommands — zawiera konstytucje udostępnione przez serwer i klienta.
- ChatSettings — Przechowuje różne ustawienia, aby skonfigurować różne aspekty Okienka czatu.
- ChatLocalization — struktura danych, która przechowuje tłumaczenia tekstowe.
- ChatServiceRunner — ten Script bieżący komponent serwera czatu. W ogóle nie musi być zmieniany, aby utworzyć niestandardowy zachowanie i funkcjonalność czatu.
- BubbleChat — Wyświetla wiadomości czatu użytkownika ponad ich własnym avatarem w grze (jeśli jest to włączone).
- ChatScript — Ten LocalScript bieżący komponent klienta czatu. Podobnie jak ChatServiceRunner, ten nie powinien być modyfikowany, aby dostosować czat. Gdy gra uruchomuje to, zostanie automatycznie sklonowana do StarterPlayerScripts .
Modyfikacja systemu czatu
Aby zmodyfikować lub dostosować system czatu dziedzicznego, musisz najpierw zrobić kopię hierarchii powyżej.
W oknie Explorer, znajdź TextChatService. Następnie, w oknie Proprietści, ustaw właściwość 2> ChatVersion2> na 5> LegacyChatService5>.
Zacznij doświadczenie używając przycisku Graj ( F5 ).
Wybierz i skopiuj ( CtrlC lub ⌘C ) obiekty, które są dodane do 2> Class.Czat2> .
Zatrzymaj doświadczenie przy użyciu przycisku Zatrzymaj ( ShiftF5 ).
Wybierz Chat i wklej w ( Ctrl 0> Shift 0> 2> V2> lub 5> ⌘5> 7> Shift7> 9> V9>).
Upewnij się, że Chat.LoadDefaultChat jest Włączone.
Praca w czacie
Zanim tworzysz moduły do personalizacji czatu, ważne jest, aby zrozumieć workflow, przez który przechodzi wiadomość czatu. Wraz z wysyłaniem wiadomości tekstowych istnieje wiele komend zbudowanych w systemie czatu, więc każda wiadomość musi być sprawdzana, aby ujrzeć, czy musi być interpretowana jako komenda lub tylko wiadomość tekstowa. Nawet wiadomości tekstowe mogą być zmodyfikowane i filtrow
Po tym, jak użytkownik skupi się na polu wpisu w czacie i wpisze postać, kilka czynności zostanie natychmiastowo wykonanych na klient. Jeśli postać jest Esc, pola wpis
Na stronie klienta czatu jest dwa rodzaje procesorów: W toku i Ukończony. Pierwszy ocenia po każdym znaku zostać wpisany, podczas gdy ten drugi ocenia tylko po zakończeniu pisania i dotarciu do Enter.
Gdy użytkownik kończy pisanie i naciśnie Enter, tekst jest wysyłany przez kilka innych procesorów komend. Jeśli użyto In-Progress komendy, czat sprawdza stan, aby ujrzeć, czy ostateczny komendy powinny być wykonane, a jeśli wiadomo
Gdy wiadomość dotrze do serwera, przeszedł через kolej z serwerów do zarządzania komendami. Podobnie jak zakończone procesory na klientach, jeśli którykolwiek z tych procesorów zwraca prawdę, wiadomość przestaje być wykonana. W przeciwnym razie wiadomość jest przesyłana na wszystkie kanały i odpowiednie głośniki.
Moduły serwera
Moduły umieszczone w ChatModule mogą być używane do różnych celów. Te moduły można używać do zarządzania kanałami czatu i głośnikami, dodawać filtry i funkcje komend, uruchomić chatboty lub cokolwiek innego, co musi być zarządzane na serwerze. Aby wejść w interakcję z systemem czatu, każdy moduł otrzymuje obiekt ChatService.
Gdy ChatServiceRunner zostanie uruchomiony, wymaga każdego modułu w ChatModule. Oczekuje, że każdy moduł zwraca funkcję, gdy następnie wzywa każdy z modułów w kolejności, przesyłając w nim swoje ChatService obiekt do każdej funkcji. Niezależnie od tego, co moduł ma zamiar z
Szablonowy rama modułowa
local function Run(ChatService)
-- Kod wpisać tutaj
end
return Run
Dodawanie kanałów
Jedną z najprostszych rzeczy, jakie może zrobić ChatModule jest zarządzanie kanałami . Objekty kanału można tworzyć za pomocą metody AddChannel() z 1>ChatService1> lub 4>ChatSpeakers4>. Uw
local function Run(ChatService)
local myChannel = ChatService:AddChannel("MyChannel")
end
return Run
Podstawowe konfiguracje kanału
Kanały mają kilka właściwości, które można użyć do nieco zmodyfikowania ich. Na przykład ten moduł tworzy kanał i ustawia wiadomość powitania, a użytkownicy automatycznie dołączają do kanału, gdy wchodzą do doświadczenia.
local function Run(ChatService)
local myChannel = ChatService:AddChannel("MyChannel")
-- Ustaw wiadomość, która jest wyświetlana, gdy użytkownik dołącza do kanału
myChannel.WelcomeMessage = "Welcome to my channel!"
-- Powoduje, że gracze automatycznie dołączają do kanału, gdy wejdą do gry
myChannel.AutoJoin = true
end
return Run
Wydarzenia kanału
Kanały mają kilka wydarzeń, które można subskrybować. Te wydarzenia dzieją się, gdy ChatMessage zostanie opublikowany na kanale, gdy ChatSpeaker opuści lub dołączy lub gdy głośnik zostanie zmutowany lub odblokowany. Na przykład ten moduł stworzy kanał z nazwą
local function Run(ChatService)
local myChannel = ChatService:AddChannel("MyChannel")
local function onSpeakerJoined(speakerName)
myChannel:SendSystemMessage(speakerName .. " has joined the channel.")
end
local function onSpeakerLeft(speakerName)
myChannel:SendSystemMessage(speakerName .. " has left the channel.")
end
myChannel.SpeakerJoined:Connect(onSpeakerJoined)
myChannel.SpeakerLeft:Connect(onSpeakerLeft)
end
return Run
Funkcje komend
Kolejną potężną rzeczą, którą ChatModule może zrobić, są komendy kanał. Gdy wiadomość jest wys
Funkcje komend są często używane do implementacji Komendy Admina, które są komendami tekstowymi, które niektórzy użytkownicy mogą używać do manipulacji stanem doświadczenia poprzez określony tekst powiedziano w czacie.
W tym przykładzie używany jest ChatModule, aby stworzyć Part, jeśli użytkownik wpisze /part w czacie. Uwaga, że ta funkcja zwraca prawdę, jeśli część została utworzona, co powoduje, że wiadomość nie będzie wyświetlana. Jeśli część nie została utworzona, ta fun
local function Run(ChatService)
local function createPart(speakerName, message, channelName)
if string.sub(message, 1, 5) == "/part" then
local newPart = Instance.new("Part")
newPart.Parent = workspace
return true
end
return false
end
ChatService:RegisterProcessCommandsFunction("createPart", createPart)
end
return Run
Zarówno Kanały czatu i ChatService sami mogą mieć komendy czatu. Kanały czatu przetwarzające komendy będą działać na każdym wysyłanym na serwer wiadomości, podczas gdy 2>Kanały czatu2> przetwarzające komendy będą działać tylko wtedy, gdy wiadomość zostanie wysłana na kanał, do którego zapisany jest komendy.
Filtry funkcji
Wiadomości, które nie są zatrzymane przez funkcję Stop-Command przechodzą przez wszystkie filtrowe funkcje zarejestrowane w ChatService i odpowiednie kanały. Każda funkcja filtra jest przekazywana przez głośnik, obiektu wiadomości i imienia wiadomość. Wszelkie zmiany w obiekcie wiadomości będą trwać i każda następna funkcja filtra będzie
W tym przykładzie zarejestrowana jest prosta funkcja filtra, aby każda wiadomość pojawiła się w mniejszej czcionce.
local function Run(ChatService)
local function makeLowercase(sender, messageObject, channelName)
messageObject.Message = string.lower(messageObject.Message)
end
ChatService:RegisterFilterMessageFunction("makeLowercase", makeLowercase)
end
return Run
Moduły Klienta
Moduły umieszczone w ClientChatModule mogą być używane do tworzenia niestandardowego zachowania dla klientów. Te moduły podzielone są na dwa różne katalogi: Katalogi Modułów Komend i Katalogi Modułów Wiadomości.
Moduły komend
Command Modules działają bardzo podobnie do modułów na serwerze, które rejestrują funkcje komend. Te moduły definiują funkcje, które zostaną uruchomione po wpisie użytkownika w tekst. Ten tekst może być czytany i
W obu rodzajach komend moduł musi zwrócić słownik, który mówi, jaki typ procesora powinien używać, i którą funkcję wykonuje, gdy procesor jest wezwany. Na przykład, ukończony procesor wiadomości powinien przyjąć formę:
local util = require(script.Parent:WaitForChild("Util"))
function ProcessMessage(message, ChatWindow, ChatSettings)
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.COMPLETED_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}
Uwaga, że KEY_COMMAND_PROCESSOR_TYPE typy są zdefiniowane w Class.ModuleScriptModuleScript w katalogu 2>CommandModuleScript2> .
Ukończone komendy wiadomości
Ukończone Komendy Wiadomości są oceniane, gdy użytkownik zakończył wpisywanie i naciśnie Enter. Funkcja przetwarzadora jest przekazywana przez obiekt ChatMessage i okno 0>ChatWindow0> serwer, a nast
Na przykład następujący procesor usunie najstarszy wiadomość w obecnym kanale, jeśli użytkownik wpisze komendę /last.
local util = require(script.Parent:WaitForChild("Util"))
function ProcessMessage(message, ChatWindow, ChatSettings)
if string.sub(message, 1, 5) == "/last" then
local currentChannel = ChatWindow:GetCurrentChannel()
if currentChannel then
currentChannel:RemoveLastMessageFromChannel()
end
return true
end
return false
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.COMPLETED_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}
Komendy w toku
Komendy w toku są ocenywane za każdym razem, gdy użytkownik wpisuje postać w polu czatu. Na przykład, następujący kod gra klak po każdym naciśnięciu klawisza, aby to zadźwięczyć jak użytkownik pisze na klawiaturze:
local util = require(script.Parent:WaitForChild("Util"))
local keyEffect = Instance.new("Sound")
keyEffect.SoundId = "rbxassetid://12221976"
keyEffect.Parent = script
function ProcessMessage(message, ChatWindow, ChatBar, ChatSettings)
keyEffect:Play()
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.IN_PROGRESS_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}
Komendy w toku są często używane do ustawienia ustawienia użytkownika dla czatu, aby wysyłały wiadomości do określonych użytkowników zamiast tylko obecnego kanału. Na przykład systemy Whisper i Team Chat sprawdzają, czy użytkownik wpisał /whisper lub /team odpowiednio i wysyłają uko
Oczekuje się, że niestandardowy stan będzie tabelą z następującymi funkcjami:
- TextUpdated() — Wezwano, gdy tekst w polu wpisu się zmienił.
- GetMessage() — Wezwano po zakończeniu wpisu użytkownika i dotarło Enter . Ta funkcja powinna zwrócić ciąg.
- ProcessCompletedMessage() — Wezwano jako że wiadomość jest przetwarzana. Procesor stanu niestandardowy zawsze wstrzyma wysyłanie wiadomości, aby wiadomość zakończyła się. Podobnie jak inne procesory funkcja ta zawsze powinna zwracać prawdę, jeśli wiadomość nie zostanie wysłana.
- Destroy() — Wezwano po wysłaniu wiadomości. Powinno być używane do czyszczenia wszystkiego, co ustawione przez niestandardowy stan.
Aby użyć niestandardowego stanu, funkcja ProcessMessage() modułu komendowego musi zwrócić stan. Podstawowy niestandardowy stan będzie miał następujący kształt:
local util = require(script.Parent:WaitForChild("Util"))
local oneLineState = {}
oneLineState.__index = oneLineState
function oneLineState:TextUpdated()
local text = self.TextBox.Text
local length = string.len(text)
if length > 20 then
local chopLength = length - 20
local addToPrefix = string.sub(text, 1, chopLength)
self.Prefix = self.Prefix .. addToPrefix
self.TextBox.Text = string.sub(text, chopLength + 1)
end
end
function oneLineState:GetMessage()
local fullString = self.Prefix .. self.TextBox.Text
return fullString
end
function oneLineState:ProcessCompletedMessage()
return false
end
function oneLineState:Destroy()
self.Destroyed = true
end
function oneLineState.new(ChatWindow, ChatBar, ChatSettings)
local obj = {}
setmetatable(obj, oneLineState)
obj.Destroyed = false
obj.ChatWindow = ChatWindow
obj.ChatBar = ChatBar
obj.ChatSettings = ChatSettings
obj.TextBox = ChatBar:GetTextBox()
obj.MessageModeLabel = ChatBar:GetMessageModeTextLabel()
obj.Prefix = ""
return obj
end
local function ProcessMessage(message, ChatWindow, ChatBar, ChatSettings)
return oneLineState.new(ChatWindow, ChatBar, ChatSettings)
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.IN_PROGRESS_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}
Jednym z głównych zalet używania niestandardowego stanu jest to, że moduł może edytować czat bar i jego zawierający tekst, podczas gdy użytkownik wpisuje obie w kategoriach funkcji i wyglądu, a następnie łatwo go zresetuje (po wysłaniu wiadomośćw trybie wiadomość
local util = require(script.Parent:WaitForChild("Util"))
local oneLineState = {}
oneLineState.__index = oneLineState
function oneLineState:TextUpdated()
local text = self.TextBox.Text
local length = string.len(text)
if length > 20 then
local chopLength = length - 20
local addToPrefix = string.sub(text, 1, chopLength)
self.Prefix = self.Prefix .. addToPrefix
self.TextBox.Text = string.sub(text, chopLength + 1)
end
end
function oneLineState:GetMessage()
local fullString = self.Prefix .. self.TextBox.Text
return fullString
end
function oneLineState:ProcessCompletedMessage()
return false
end
function oneLineState:Destroy()
self.Destroyed = true
end
function oneLineState.new(ChatWindow, ChatBar, ChatSettings)
local obj = {}
setmetatable(obj, oneLineState)
obj.Destroyed = false
obj.ChatWindow = ChatWindow
obj.ChatBar = ChatBar
obj.ChatSettings = ChatSettings
obj.TextBox = ChatBar:GetTextBox()
obj.MessageModeLabel = ChatBar:GetMessageModeTextLabel()
obj.Prefix = ""
return obj
end
local function ProcessMessage(message, ChatWindow, ChatBar, ChatSettings)
return oneLineState.new(ChatWindow, ChatBar, ChatSettings)
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.IN_PROGRESS_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}
Jak wspomniano wcześniej, po wysłaniu jakiejkolwiek wiadomości, każdy niestandardowy stan jest usuwany i czat jest przywracany do normy. Jeśli konieczne jest zresetowanie jakiegoś stanu niestandardowego przed wysłaniem wiadomość, stan można zresetować za pomocą ChatBar:ResetCustomState() . Uwaga, że to usunie skupienie z pola tekstowego chatu.
Moduły twórcy wiadomości
Kolejnym typem modułu, który może być używany w komponentach klienta, jest moduł Twórca wiadomości . Ten typ modułu jest używany do tworzenia elementów GUI w oknie czatu, aby wyświetlić wiadomość. Każdy typ twórcy wiadomości definuje nowy wpisywaćwiadomości, więc różne wiadomości mogą być tworzone z różnymi formami.
Te moduły wymagają ustawień w kilku różnych lokalizacjach. Dla każdego wpisywaćwiadomości musi istnieć ModuleScript w MessageCreatorModule . Ponadto, ChatCommands2> Class.ModuleScript2> musi być edytowany, aby zaimplementować nowy wpisywaćwiadomości. Aby wpisywaćby
Poniższy przykład pokaże, jak zrobić bota, który mówi czas co 5 sekund, a wiadomość wysłana dostanie czerwony tło.
Aby rozpoczynać, ChatSuppressModuleScript musi dodać pola dla nowego rodzaju wiadomość.
-- Czatlocal module = {}--<- [[ Typy wiadomości ]]module.MessageTypeDefault = "Message"module.MessageTypeSystem = "System"module.MessageTypeMeCommand = "MeCommand"module.MessageTypeWelcome = "Welcome"module.MessageTypeSetCore = "SetCore"module.MessageTypeWhisper = "Whisper"module.MessageTypeTime = "Time"module.MajorVersion = 0module.MinorVersion = 2return module
Bot sam w sobie jest stworzony w nowym ChatModule na serwerze. Uwaga, że funkcja filtra jest używana do dodania nowego typu wiadomości do wiadomości, które wysyłuje bot.
-- Nowy moduł do umieszczenia w ChatModule
local Chat = game:GetService("Chat")
local ReplicatedModules = Chat:WaitForChild("ClientChatModules")
local ChatConstants = require(ReplicatedModules:WaitForChild("ChatConstants"))
local function Run(ChatService)
local timeBot = ChatService:AddSpeaker("TimeBot")
timeBot:JoinChannel("All")
local function addMessageType(speaker, messageObject, channelName)
if speaker == "TimeBot" then
messageObject.MessageType = ChatConstants.MessageTypeTime
end
end
ChatService:RegisterFilterMessageFunction("TimeBotFilter", addMessageType)
task.spawn(function()
while task.wait(5) do
timeBot:SayMessage("The current time is: " .. os.time(), "All", {})
end
end)
end
return Run
Na koniec, moduł twórcy wiadomości musi zostać stworzony. Ten moduł musi zwrócić słownik z dwoma elementami: typ wiadomość, zindeksowany z KEY_MESSAGE_TYPE i funkcję do wzywania, gdy tworzy się elementy GUI wiadomości, zindeksowane z KEY_CREATOR_FUNCTION .
Funkcja zapisana przez KEY_CREATOR_FUNCTION musi zwrócić dyktwardzik z kilku składników. Po
-- nowy ModuleScript do zostań włączony w MessageCreatorModule
local messageCreatorModules = script.Parent
local util = require(messageCreatorModules:WaitForChild("Util"))
local clientChatModules = messageCreatorModules.Parent
local ChatSettings = require(clientChatModules:WaitForChild("ChatSettings"))
local ChatConstants = require(clientChatModules:WaitForChild("ChatConstants"))
local function CreateMessageLabel(messageData, channelName)
-- Utwórz obiekty GUI dla ramy i tekstu Label, aby pomieścić wiadomość
local BaseFrame, BaseMessage = util:CreateBaseMessage("", ChatSettings.DefaultFont, ChatSettings.ChatWindowTextSize, ChatSettings.DefaultMessageColor)
-- Zmień tło ramy na czerwony
BaseFrame.BackgroundColor3 = Color3.new(1,0,0)
BaseFrame.BackgroundTransparency = 0
-- Zmień tekst wiadomości zmiany statusu
local function UpdateTextFunction(messageObject)
if messageObject.IsFiltered then
BaseMessage.Text = messageObject.Message
end
end
UpdateTextFunction(messageData)
-- Użyj funkcji util, aby określić wysokość ramy
local function GetHeightFunction(xSize)
return util:GetMessageHeight(BaseMessage, BaseFrame, xSize)
end
-- Utwórz funkcje zanikania, które są wzywane, gdy okno czatu zanika
local FadeParameters = {}
FadeParameters[BaseMessage] = {
TextTransparency = {FadedIn = 0, FadedOut = 1},
TextStrokeTransparency = {FadedIn = 0.75, FadedOut = 1}
}
local FadeInFunction, FadeOutFunction, UpdateAnimFunction = util:CreateFadeFunctions(FadeParameters)
-- Wróć do słownika, który określa wiadomość
return {
[util.KEY_BASE_FRAME] = BaseFrame,
[util.KEY_BASE_MESSAGE] = BaseMessage,
[util.KEY_UPDATE_TEXT_FUNC] = UpdateTextFunction,
[util.KEY_GET_HEIGHT] = GetHeightFunction,
[util.KEY_FADE_IN] = FadeInFunction,
[util.KEY_FADE_OUT] = FadeOutFunction,
[util.KEY_UPDATE_ANIMATION] = UpdateAnimFunction
}
end
return {
[util.KEY_MESSAGE_TYPE] = ChatConstants.MessageTypeTime,
[util.KEY_CREATOR_FUNCTION] = CreateMessageLabel
}