Привет, от нечего делать, мне стало интересно как можно реализовать собственный чат в Rage MP. Не много покопавшись на форуме Rage MP я нашел пример от разработчиков дефолтного чата Rage MP, разобрашись в коде, я решил что нужно его переделать на Vue, ведь дефолтый чат написал на JQuery, а как по мне это уже устаревшая библиотека и нужно быть в тренде.
Осталось еще на клиенте указать что это у нас будет чат.
Ну и на серверной части:
Если у вас будут какие-либо вопросы - задавайте. Постарался все моменты описать, но кто его знает, возможно кому-то этого будет недостаточно. Так что не стесняйтесь и задавайте вопросы.
JavaScript:
<template>
<div>
<div v-if="showChat" id="chat">
<ul id="chat_messages">
<li v-for="message in chatMessages" :key="message">
{{ message }}
</li>
</ul>
<input v-show="showInput" v-model="inputText" ref="input" id="chat_msg" type="text" />
</div>
</div>
</template>
<script>
export default {
name: 'RageMPChat',
keys: {
KEY_T: 84,
KEY_ENTER: 13
},
data() {
return {
showInput: false, // Отвечает за показ ввода текста
showChat: false, // Отвечает за показ нашего чата
chatMessages: [], // список сообщений в чате
inputText: '', // Тут хранится наш текст, который мы вводим в инпут
active: true // Отвечает за возможность писать в чат
}
},
methods: {
// Это у нас обработчик нажатия клавиш
addKeyListener(e) {
// Если мы нажимаем Т и у нас еще не показан инпут и можно писать в чат
if (e.which === this.$options.keys.KEY_T && !this.showInput && this.active) {
// показываем инпут
this.enableChatInput(true);
e.preventDefault();
return;
}
// если мы нажали Ентер и у нас открыт инпут
if (e.which === this.$options.keys.KEY_ENTER && this.showInput) {
let text = this.inputText;
// закрываем инпут
this.enableChatInput(false);
if (!text.length) {
return;
}
// если это не команда - значит сообщение xD
if (text.charAt(0) !== "/") {
mp.invoke("chatMessage", text);
return;
}
// тут мы избавляемся от "/"
text = text.substr(1);
if (text.length) {
mp.invoke("command", text);
}
}
},
// Пушим наше сообщение в чатбокс
push(text) {
if (this.chatMessages.length >= 50) {
this.chatMessages.shift();
}
this.chatMessages.unshift(text);
},
// очищаем наш список сообщениц
clear() {
this.chatMessages.length = 0;
},
// показать / убрать интуп ввода текста
enableChatInput(enable) {
if (!this.active && enable) {
return;
}
if (enable !== this.showInput) {
mp.invoke("focus", enable);
mp.invoke("setTypingInChatState", enable);
this.showInput = enable;
this.inputText = '';
enable && this.$nextTick().then(() => this.$refs.input.focus());
}
},
// включить / отключить возможность писать в чат
activate(toggle) {
if (!toggle && this.showInput) {
this.enableChatInput(false);
}
this.active = toggle;
},
// показать / скрыть чат
show(toggle) {
if (!toggle && this.showInput) {
this.enableChatInput(false);
}
this.showChat = toggle;
}
},
created() {
if (mp.events) {
const api = {
"chat:push": this.push,
"chat:clear": this.clear,
"chat:activate": this.activate,
"chat:show": this.show
};
// Тут мы добавляем ивенты на клиент
for (const fn in api) {
mp.events.add(fn, api[fn]);
}
// Теперь, если я все правильно понял у нас
// mp.gui.chat.push(text) - выполняет функцию this.push(text) - то-есть добавляет сообщение в чат
// mp.gui.chat.show(toggle) - this.show(toggle)
// mp.gui.chat.clear() - this.clear()
// mp.gui.chat.active(toggle) - this.active(toggle)
}
// Добавляем наш обработчик в событие
document.addEventListener("keydown", this.addKeyListener);
},
beforeUnmount() {
// Удалем наш обработчик из события
document.removeEventListener("keydown", this.addKeyListener);
},
mounted() {
// Включаем чат
this.showChat = true;
this.push("Multiplayer started!!!");
}
}
</script>
// Это дефолт стили чата Rage MP
<style scoped>
*, body, html {
padding: 0;
margin: 0
}
#chat, a, body, html {
color: #fff
}
body, html {
-webkit-font-smoothing: antialiased;
overflow: hidden;
font-size: 14px;
-webkit-user-select: none
}
#chat {
width: 800px;
line-height: 24px;
font-weight: 700;
text-shadow: 1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
font-family: "Arial", sans-serif;
font-size: 16px;
margin-left: 15px;
}
@media screen and (min-height: 1080px) {
#chat {
font-size: 18px !important;
font-weight: 700;
}
}
#chat ul#chat_messages {
height: 285px;
margin-top: 2vh; /*2vh*/
transform: rotate(180deg);
padding: 10px 20px; /* old padding: 10px 20px*/
list-style-type: none;
overflow: auto;
}
#chat ul#chat_messages > li {
transform: rotate(-180deg)
}
#chat input#chat_msg {
color: #fff;
background-color: rgba(208,60,55,0.7);
outline: 0;
border: none;
font-family: Myriad Pro, Open Sans, sans-serif;
font-size: 13px;
line-height: 35px;
width: 35vw;
padding: 5px 5px 5px 15px
}
::-webkit-scrollbar {
width: 11px;
}
::-webkit-scrollbar-thumb {
background: rgba(255, 17, 0, 0.3);
border-radius: 20px
}
::-webkit-scrollbar-thumb:hover {
background: rgba(255, 17, 0, 0.65)
}
</style>
JavaScript:
module.exports = {
publicPath: './',
lintOnSave: process.env.NODE_DEV !== "production"
}
JavaScript:
let customChat = null;
mp.events.add('guiReady', () => {
if (!customChat) {
mp.gui.chat.show(false);
customChat = mp.browsers.new(/*Тут ваш путь к .html*/);
customChat.markAsChat();
}
})
JavaScript:
mp.events.add('playerChat', (player, text) => {
player.outputChatBox(`${player.name}: ${text}`);
});
Если у вас будут какие-либо вопросы - задавайте. Постарался все моменты описать, но кто его знает, возможно кому-то этого будет недостаточно. Так что не стесняйтесь и задавайте вопросы.
Последнее редактирование: