Browse Source

Merge branch 'master' into 'release'

bug #2001: Fixed text rendering over emoji tags when the text is multiline....

See merge request Isleward/isleward!632
tags/v0.13.0^0
Big Bad Waffle 6 months ago
parent
commit
8fed69c99d
34 changed files with 3570 additions and 3445 deletions
  1. +0
    -1
      .gitignore
  2. +8
    -6
      .gitlab-ci.yml
  3. +0
    -3
      src/.eslintignore
  4. +1
    -1
      src/client/.eslintrc
  5. +8
    -0
      src/client/css/main.less
  6. +0
    -1
      src/client/js/main.js
  7. +1
    -4
      src/client/js/system/events.js
  8. +13
    -0
      src/client/package-lock.json
  9. +2
    -7
      src/client/package.json
  10. +1
    -1
      src/client/ui/factory.js
  11. +2
    -2
      src/client/ui/templates/login/template.html
  12. +4
    -4
      src/client/ui/templates/messages/messages.js
  13. +14
    -5
      src/client/ui/templates/messages/styles.less
  14. +0
    -177
      src/client/ui/templates/online/online.js
  15. +0
    -100
      src/client/ui/templates/online/styles.less
  16. +0
    -14
      src/client/ui/templates/online/template.html
  17. +0
    -5
      src/client/ui/templates/online/templateListItem.html
  18. +12
    -24
      src/client/ui/templates/party/party.js
  19. +2927
    -0
      src/package-lock.json
  20. +14
    -0
      src/package.json
  21. +1
    -1
      src/server/.eslintignore
  22. +14
    -1
      src/server/.eslintrc
  23. +1
    -12
      src/server/components/equipment.js
  24. +2
    -24
      src/server/components/player.js
  25. +2
    -2
      src/server/components/social.js
  26. +28
    -10
      src/server/components/social/chat.js
  27. +2
    -2
      src/server/components/trade.js
  28. +1
    -1
      src/server/config/serverConfig.js
  29. +7
    -2
      src/server/objects/objects.js
  30. +496
    -3012
      src/server/package-lock.json
  31. +1
    -5
      src/server/package.json
  32. +5
    -16
      src/server/security/connections.js
  33. +0
    -1
      src/server/server/requestHandlers.js
  34. +3
    -1
      src/server/world/atlas.js

+ 0
- 1
.gitignore View File

@@ -1,5 +1,4 @@
node_modules
package-lock.json
*.css

storage.db


+ 8
- 6
.gitlab-ci.yml View File

@@ -17,9 +17,10 @@ audit:
lint-server:
stage: test
script:
- npm install eslint@7.32.0 eslint-plugin-prettier prettier babel-eslint eslint-plugin-requirejs
- cd src/server
- ../../node_modules/.bin/eslint .
- cd src
- npm install
- cd server
- ../node_modules/.bin/eslint .
only:
- merge_requests
- master
@@ -27,9 +28,10 @@ lint-server:
lint-client:
stage: test
script:
- npm install eslint@7.32.0 eslint-plugin-prettier prettier babel-eslint eslint-plugin-requirejs
- cd src/client
- ../../node_modules/.bin/eslint .
- cd src
- npm install
- cd client
- ../node_modules/.bin/eslint .
only:
- merge_requests
- master


+ 0
- 3
src/.eslintignore View File

@@ -1,3 +0,0 @@
/client/plugins/*
node_modules/*
*.json

+ 1
- 1
src/client/.eslintrc View File

@@ -220,7 +220,7 @@
"no-throw-literal": 2,
"no-undef": 1,
"no-undef-init": 2,
"no-underscore-dangle": 1,
"no-underscore-dangle": 0,
"no-unneeded-ternary": 2,
"no-unreachable": 1,
"no-unused-expressions": 2,


+ 8
- 0
src/client/css/main.less View File

@@ -206,6 +206,14 @@ body {
color: @qualityLegendary;
}

.chat-style-white {
color: @white !important;
}

.chat-style-cyan {
color: @blueA !important;
}

.color-red {
color: @redB !important;
}


+ 0
- 1
src/client/js/main.js View File

@@ -11,7 +11,6 @@ define([
'js/sound/sound',
'js/system/globals',
'js/components/components',
'ui/templates/online/online',
'ui/templates/tooltips/tooltips'
], function (
client,


+ 1
- 4
src/client/js/system/events.js View File

@@ -26,10 +26,7 @@ define([
return callback;
},
clearQueue: function () {
//Hack to allow the player list to persist
this.queue.spliceWhere(function (q) {
return ((q.event !== 'onGetConnectedPlayer') && (q.event !== 'onGetDisconnectedPlayer'));
});
this.queue.length = 0;
},
off: function (eventName, callback) {
let list = this.events[eventName] || [];


+ 13
- 0
src/client/package-lock.json View File

@@ -0,0 +1,13 @@
{
"name": "isleward_client",
"version": "0.12.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "isleward_client",
"version": "0.12.0",
"devDependencies": {}
}
}
}

+ 2
- 7
src/client/package.json View File

@@ -1,13 +1,8 @@
{
"name": "isleward_client",
"version": "0.12.0",
"version": "0.13.0",
"description": "isleward",
"dependencies": {
},
"devDependencies": {
"eslint": "^7.32.0",
"babel-eslint": "^10.1.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-requirejs": "^4.0.1"

}
}

+ 1
- 1
src/client/ui/factory.js View File

@@ -97,7 +97,7 @@ define([
else
path = this.root + 'ui/templates/' + type + '/' + type;
}
require([path], this.onGetTemplate.bind(this, options, type));
},


+ 2
- 2
src/client/ui/templates/login/template.html View File

@@ -11,11 +11,11 @@
</div>
<div class="message"></div>
</div>
<div class="news" location="https://gitlab.com/Isleward/play.isleward.com/-/wikis/v0.12.0-Release-Notes">[ Latest Release Notes ]</div>
<div class="news" location="https://gitlab.com/Isleward/play.isleward.com/-/wikis/v0.13.0-Release-Notes">[ Latest Release Notes ]</div>
<div class="extra">
<div class="el btn btnPatreon monetization" location="https://patreon.com/bigbadwaffle">Pledge on Patreon</div>
<div class="el btn btnPaypal monetization" location="https://www.paypal.com/donate?hosted_button_id=NEQAV3NG9PWXA">Donate on Paypal</div>
<div class="el btn btnWiki" location="http://wiki.isleward.com/Main_Page">Access the Wiki</div>
</div>
<div class="version" location="https://gitlab.com/Isleward/play.isleward.com/-/wikis/v0.12.0-Release-Notes">v0.12.0</div>
<div class="version" location="https://gitlab.com/Isleward/play.isleward.com/-/wikis/v0.13.0-Release-Notes">v0.13.0</div>
</div>

+ 4
- 4
src/client/ui/templates/messages/messages.js View File

@@ -214,8 +214,8 @@ define([
}

if (m.item) {
let source = message.split(':')[0];
message = source + ': <span class="q' + (m.item.quality || 0) + '">' + message.replace(source + ': ', '') + '</span>';
const [source, useMessage] = message.split(': {');
message = source + ': <span class="q' + (m.item.quality || 0) + '">&nbsp;{' + useMessage + '</span>';
}

let el = $('<div class="list-message ' + m.class + '">' + message + '</div>')
@@ -245,9 +245,9 @@ define([
const isChannel = m?.subType === 'custom';
if (isChannel) {
if (this.find('.filter[filter="' + m.channel + '"]').hasClass('active'))
el.show();
el.css({ display: 'flex' });
else
el.hide();
el.css({ display: 'none' });
}

if (isMobile && ['loot', 'info'].indexOf(m.type) !== -1) {


+ 14
- 5
src/client/ui/templates/messages/styles.less View File

@@ -53,6 +53,7 @@

.list-message {
display: none;
justify-content: row;
width: 100%;
padding: 5px 10px;
color: white;
@@ -64,7 +65,7 @@
drop-shadow(0px 2px 0px @blackD)
drop-shadow(2px 0px 0px @blackD)
drop-shadow(-2px 0px 0px @blackD);
word-wrap: break-word;
word-wrap: anywhere;
line-height: 18px;

&.q {
@@ -111,19 +112,27 @@
}

&.rep .rep {
display: block;
display: flex;
}

&.chat .chat {
display: block;
display: flex;
}

&.info .info {
display: block;
display: flex;
}

&.loot .loot {
display: block;
display: flex;
}

.emojiTag {
width: 24px;
height: 24px;
margin-top: -4px;
margin-right: 5px;
flex-shrink: 0;
}

}


+ 0
- 177
src/client/ui/templates/online/online.js View File

@@ -1,177 +0,0 @@
define([
'js/system/events',
'js/system/client',
'js/system/globals',
'html!ui/templates/online/template',
'css!ui/templates/online/styles',
'html!ui/templates/online/templateListItem'
], function (
events,
client,
globals,
template,
styles,
templateListItem
) {
return {
tpl: template,
centered: true,

onlineList: [],

modal: true,
hasClose: true,

actions: [],

postRender: function () {
globals.onlineList = this.onlineList;

this.onEvent('onGetConnectedPlayer', this.onGetConnectedPlayer.bind(this));
this.onEvent('onGetDisconnectedPlayer', this.onGetDisconnectedPlayer.bind(this));

this.onEvent('onGetSocialActions', this.onGetSocialActions.bind(this));

this.onEvent('onKeyDown', this.onKeyDown.bind(this));
this.onEvent('onShowOnline', this.toggle.bind(this));
},

onGetSocialActions: function (actions) {
this.actions = actions;
},

onKeyDown: function (key) {
if (key === 'o')
this.toggle();
},

onAfterShow: function () {
this.build();
},

onGetConnectedPlayer: function (list) {
if (!list.length)
list = [list];

let onlineList = this.onlineList;

list.forEach(function (l) {
let exists = onlineList.find(function (o) {
return (o.name === l.name);
});
if (exists)
$.extend(true, exists, l);
else
onlineList.push(l);
});

onlineList
.sort(function (a, b) {
if (a.level === b.level) {
if (a.name > b.name)
return 1;
return -1;
} return b.level - a.level;
});

if (this.shown)
this.build();
},

onGetDisconnectedPlayer: function (playerName) {
let onlineList = this.onlineList;

onlineList.spliceWhere(function (o) {
return (o.name === playerName);
});

if (this.shown)
this.build();
},

build: function () {
let headingText = this.el.find('.heading-text');
let playerCount = this.onlineList.length;
headingText.html(`online players (${playerCount})`);

let container = this.el.find('.list');
container
.children(':not(.heading)')
.remove();

this.onlineList.forEach(function (l) {
let html = templateListItem
.replace('$NAME$', l.name)
.replace('$LEVEL$', l.level)
.replace('$CLASS$', l.class);

let el = $(html)
.appendTo(container)
.on('contextmenu', this.showContext.bind(this, l));

if (isMobile)
el.on('mousedown', this.showContext.bind(this, l));
}, this);
},

showContext: function (char, e) {
if (char.name !== window.player.name) {
const extraActions = this.actions.map(({ command, text }) => {
return {
text,
callback: this.performAction.bind(this, command, char.name)
};
});

const isBlocked = window.player.social.isPlayerBlocked(char.name);

const actions = [{
text: 'invite to party',
callback: this.invite.bind(this, char.id)
}, {
text: 'whisper',
callback: events.emit.bind(events, 'onDoWhisper', char.name)
}, {
text: isBlocked ? 'unblock' : 'block',
callback: this.block.bind(this, char.name)
}, ...extraActions];

events.emit('onBeforeOnlineListContext', char.id, actions);
events.emit('onContextMenu', actions, e);
}

e.preventDefault();
return false;
},

performAction: function (command, charName) {
client.request({
cpn: 'social',
method: 'chat',
data: {
message: `/${command} ${charName}`
}
});
},

block: function (charName) {
const isBlocked = window.player.social.isPlayerBlocked(charName);
let method = isBlocked ? 'unblock' : 'block';

this.performAction(method, charName);
},

invite: function (charId) {
this.hide();

client.request({
cpn: 'social',
method: 'getInvite',
data: {
targetId: charId
}
});
}
};
});

+ 0
- 100
src/client/ui/templates/online/styles.less View File

@@ -1,100 +0,0 @@
@import "../../../css/colors.less";

.uiOnline {
display: none;
background-color: @blackB;
border: 5px solid @blackB;
text-align: center;
width: 450px;
height: 396px;

> .heading {
color: @blueA;
width: 100%;
height: 36px;
background-color: @blackB;

.heading-text {
padding-top: 8px;
margin: auto;
}

}

.bottom {
height: calc(100% - 36px);
background-color: @blackC;
padding: 8px;

.list {
width: 100%;
height: 100%;
overflow-y: auto;
background-color: @blackC;
display: flex;
flex-direction: column;

.heading {
height: 24px;
color: @white;

> div {
float: left;
padding: 4px;
height: 24px;

&:nth-child(1) {
width: 10%;
}

&:nth-child(2) {
width: 55%;
}

&:nth-child(3) {
width: 35%;
}

}

}

.onlineUser {
color: @grayC;
height: 24px;
cursor: pointer;

> div {
float: left;
padding: 4px;
height: 24px;

&:nth-child(1) {
width: 10%;
}

&:nth-child(2) {
width: 55%;
}

&:nth-child(3) {
width: 35%;
}

}

&:hover {
background-color: @blackB;
}

}

}

}

}

.mobile .uiOnline {
z-index: 2;
}

+ 0
- 14
src/client/ui/templates/online/template.html View File

@@ -1,14 +0,0 @@
<div class="uiOnline hasBorderShadow">
<div class="heading">
<div class="heading-text">online players</div>
</div>
<div class="bottom">
<div class="list">
<div class="heading">
<div class="col">level</div>
<div class="col">name</div>
<div class="col">spirit</div>
</div>
</div>
</div>
</div>

+ 0
- 5
src/client/ui/templates/online/templateListItem.html View File

@@ -1,5 +0,0 @@
<div class="onlineUser">
<div class="level">$LEVEL$</div>
<div class="name">$NAME$</div>
<div class>($CLASS$)</div>
</div>

+ 12
- 24
src/client/ui/templates/party/party.js View File

@@ -30,7 +30,7 @@ define([
this.onEvent('onGetParty', this.onGetParty.bind(this));
this.onEvent('onPartyDisband', this.onPartyDisband.bind(this));

this.onEvent('onGetConnectedPlayer', this.onGetConnectedPlayer.bind(this));
this.onEvent('globalObjectListUpdated', this.globalObjectListUpdated.bind(this));

this.onEvent('onGetPartyStats', this.onGetPartyStats.bind(this));

@@ -38,46 +38,34 @@ define([
this.onTogglePartyView(config.partyView);
},

onGetConnectedPlayer: function (msg) {
globalObjectListUpdated: function ({ list }) {
if (!window.player)
return;

const { party } = this;
const { player: { serverId: playerId, zoneId: playerZone } } = window;
const { player: { serverId: playerId } } = window;

const player = list.find(l => l.id === playerId);
const { zoneId: playerZone } = player;

if (!party)
return;

if (!(msg instanceof Array))
msg = [msg];

msg.forEach(m => {
const { id: mId, zoneId: mZone } = m;
list.forEach(l => {
const { id: mId, zoneId: mZone, level: mLevel } = l;

if (!party.includes(m.id))
if (!party.includes(mId))
return;

if (mId !== playerId) {
const el = this.find('.member[memberId="' + m.id + '"]');
const el = this.find('.member[memberId="' + mId + '"]');
el.removeClass('differentZone');

if (m.zoneId !== playerZone)
if (mZone !== playerZone)
el.addClass('differentZone');

el.find('.txtLevel').html('level: ' + m.level);

return;
el.find('.txtLevel').html('level: ' + mLevel);
}

party.forEach(p => {
const mObj = globals.onlineList.find(o => o.id === p);

const el = this.find('.member[memberId="' + p + '"]');
el.removeClass('differentZone');

if (mObj.zoneId !== mZone)
el.addClass('differentZone');
});
});
},



+ 2927
- 0
src/package-lock.json
File diff suppressed because it is too large
View File


+ 14
- 0
src/package.json View File

@@ -0,0 +1,14 @@
{
"name": "isleward",
"version": "0.13.0",
"description": "isleward",
"dependencies": {
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"eslint": "7.32.0",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-requirejs": "^4.0.1"
}
}

+ 1
- 1
src/server/.eslintignore View File

@@ -1,2 +1,2 @@
node_modules/*
config/passiveTree.js
config/passiveTree.js

+ 14
- 1
src/server/.eslintrc View File

@@ -306,7 +306,20 @@
"overrides": [
{
"files": [
"**/clientComponents/**/*.js"
"clientComponents/**/*"
],
"extends": "../client/.eslintrc"
},
{
"files": [
"mods/**/ui/*",
"mods/**/clientComponents/**/*"
],
"extends": "../client/.eslintrc"
},
{
"files": [
"mods/**/ui/**/*"
],
"extends": "../client/.eslintrc"
}


+ 1
- 12
src/server/components/equipment.js View File

@@ -263,19 +263,8 @@ module.exports = {
let itemId = eq[slot];
let item = inventory.findItem(itemId);

if (!item) {
console.log({
error: 'item not found',
itemId,
slot,
factionId,
tier,
character: this.obj.name,
eq: this.eq
});

if (!item)
return;
}

let factions = item.factions;
if (!factions)


+ 2
- 24
src/server/components/player.js View File

@@ -107,35 +107,13 @@ module.exports = {

atlas.addObject(this.obj, true);

cons.emit('events', {
onGetMessages: [{
messages: [{
class: 'color-blueB',
message: this.obj.name + ' has come online'
}]
}],
onGetConnectedPlayer: [cons.getCharacterList()]
eventEmitter.emit('playerObjAdded', {
obj
});

cb();
},

broadcastSelf: function () {
let obj = this.obj;

let self = {
id: obj.id,
zoneId: obj.zoneId,
name: obj.name,
level: obj.level,
class: obj.class
};

cons.emit('events', {
onGetConnectedPlayer: [self]
});
},

hasSeen: function (id) {
return (this.seen.indexOf(id) > -1);
},


+ 2
- 2
src/server/components/social.js View File

@@ -63,8 +63,8 @@ module.exports = {
});
},

chat: function (msg) {
chat(this, msg);
chat: async function (msg) {
await chat(this, msg);
},

dc: function () {


+ 28
- 10
src/server/components/social/chat.js View File

@@ -2,24 +2,42 @@ const events = require('../../misc/events');
const profanities = require('../../misc/profanities');
const canChat = require('./canChat');

const sendRegularMessage = ({ obj }, msg) => {
const sendRegularMessage = async ({ obj }, msg) => {
const charname = obj.auth.charname;

const msgEvent = {
username: obj.account,
tagPrefix: '(',
tagSuffix: ')',
tagPrefix: null,
tagSuffix: null,
tags: [],
msgStyle: 'color-grayB'
emojiTag: null,
namePrefix: '',
nameSuffix: '',
msgStyle: null,
obj
};

events.emit('onBeforeGetChatStyles', msgEvent);
await events.emit('onBeforeGetChatStyles', msgEvent);

const { emojiTag } = msgEvent;

let usePrefix = '';
if (msgEvent.tags.length)
if (emojiTag) {
const imgX = (-emojiTag.sprite[0] * emojiTag.spriteSize);
const imgY = (-emojiTag.sprite[1] * emojiTag.spriteSize);
const backgroundPosition = `${imgX}px ${imgY}px`;

usePrefix = `<div class='emojiTag' style='background: url("${emojiTag.spritesheet}") no-repeat scroll ${backgroundPosition} / auto;'></div>`;
} else if (msgEvent.tags.length > 0)
usePrefix = `${msgEvent.tagPrefix}${msgEvent.tags.join(' ')}${msgEvent.tagSuffix} `;

const finalMessage = `${usePrefix}${charname}: ${msg.data.message}`;
let useCharName = charname;
if (msgEvent.namePrefix)
useCharName = `${msgEvent.namePrefix}${useCharName}`;
if (msgEvent.nameSuffix)
useCharName = `${useCharName}${msgEvent.nameSuffix}`;

const finalMessage = `${usePrefix}${useCharName}: ${msg.data.message}`;

const item = msg.data.item ? JSON.parse(JSON.stringify(msg.data.item).replace(/(<([^>]+)>)/ig, '')) : undefined;

@@ -27,7 +45,7 @@ const sendRegularMessage = ({ obj }, msg) => {
event: 'onGetMessages',
data: {
messages: [{
class: msgEvent.msgStyle,
class: msgEvent.msgStyle ?? 'color-grayB',
message: finalMessage,
item,
type: 'chat',
@@ -157,7 +175,7 @@ const sendErrorMsg = (cpnSocial, msgString) => {
cpnSocial.sendMessage(msgString, 'color-redA');
};

module.exports = (cpnSocial, msg) => {
module.exports = async (cpnSocial, msg) => {
const { data: msgData } = msg;

if (!msgData.message)
@@ -246,5 +264,5 @@ module.exports = (cpnSocial, msg) => {
if (!messageHandler)
return;

messageHandler(cpnSocial, msg);
await messageHandler(cpnSocial, msg);
};

+ 2
- 2
src/server/components/trade.js View File

@@ -266,7 +266,7 @@ module.exports = {
let targetTrade = target.trade;

const item = this.obj.inventory.findItem(msg.itemId);
if (!item)
if (!item || item.worth <= 0 || item.eq || item.noDestroy)
return;

const oldQuantity = item.quantity;
@@ -312,7 +312,7 @@ module.exports = {
this.target = target;

let itemList = this.obj.inventory.items
.filter(i => ((i.worth > 0) && (!i.eq)));
.filter(i => i.worth > 0 && !i.eq && !i.noDestroy);
itemList = extend([], itemList);

this.obj.syncer.set(true, 'trade', 'sellList', {


+ 1
- 1
src/server/config/serverConfig.js View File

@@ -1,7 +1,7 @@
/* eslint-disable no-process-env */

module.exports = {
version: '0.12.0',
version: '0.13.0',
port: 4000,
startupMessage: 'Server: ready',



+ 7
- 2
src/server/objects/objects.js View File

@@ -1,3 +1,5 @@
const eventEmitter = require('../misc/events');

let objBase = require('./objBase');

module.exports = {
@@ -305,8 +307,11 @@ module.exports = {
class: 'color-blueB',
message: player.name + ' has reached level ' + obj.level
}]
}],
onGetConnectedPlayer: [cons.getCharacterList()]
}]
});

eventEmitter.emit('playerObjChanged', {
obj: player
});
}
},


+ 496
- 3012
src/server/package-lock.json
File diff suppressed because it is too large
View File


+ 1
- 5
src/server/package.json View File

@@ -1,6 +1,6 @@
{
"name": "isleward_server",
"version": "0.12.0",
"version": "0.13.0",
"description": "isleward",
"dependencies": {
"axios": "^0.22.0",
@@ -15,10 +15,6 @@
"universal-analytics": "^0.5.1"
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"eslint": "^7.32.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-requirejs": "^4.0.1",
"sqlite3": "^5.0.3"
}
}

+ 5
- 16
src/server/security/connections.js View File

@@ -1,5 +1,6 @@
//External Modules
const objects = require('../objects/objects');
const eventEmitter = require('../misc/events');

//Helpers
const { route, routeGlobal } = require('./connections/route');
@@ -56,14 +57,8 @@ module.exports = {
}

if (player.name) {
this.emit('events', {
onGetMessages: [{
messages: [{
class: 'color-blueB',
message: player.name + ' has gone offline'
}]
}],
onGetDisconnectedPlayer: [player.name]
eventEmitter.emit('playerObjRemoved', {
id: player.id
});

if (player.has('id'))
@@ -107,14 +102,8 @@ module.exports = {
}
});

this.emit('events', {
onGetMessages: [{
messages: [{
class: 'color-blueB',
message: player.name + ' has gone offline'
}]
}],
onGetDisconnectedPlayer: [player.name]
eventEmitter.emit('playerObjRemoved', {
id: player.id
});

//If we don't do this, the atlas will try to remove it from the thread


+ 0
- 1
src/server/server/requestHandlers.js View File

@@ -9,7 +9,6 @@ const appRoot = (req, res) => {
const appFile = (req, res) => {
let root = req.url.split('/')[1];
let file = req.params[0];
file = file.replace('/' + root + '/', '');

const validRequest = (


+ 3
- 1
src/server/world/atlas.js View File

@@ -56,7 +56,9 @@ module.exports = {
serverObj.zoneId = thread.id;
serverObj.zoneName = thread.name;

serverObj.player.broadcastSelf();
events.emit('playerObjChanged', {
obj
});

const simpleObj = obj.getSimple ? obj.getSimple(true, true) : obj;



Loading…
Cancel
Save