mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-24 13:55:04 +02:00
Update few more modules
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { compact, escapeRegExp, repeat } from 'lodash';
|
||||
import { createBinaryReader, readUint8, readUint32, readUint16 } from 'ag-sockets/dist/browser';
|
||||
import { decodeString } from 'ag-sockets/dist/utf8';
|
||||
import {
|
||||
Entity, Region, Pony, EntityState, PonyOptions, MessageType, isNonIgnorableMessage, EntityPlayerState,
|
||||
EntityOrPonyOptions, isPublicMessage, FakeEntity, Action, WorldMap, DoAction, UpdateType, DecodedUpdate,
|
||||
@@ -36,6 +35,7 @@ import { compareFriends } from '../components/services/model';
|
||||
import { canCollideWith } from '../common/collision';
|
||||
import { hasDrawLight, hasLightSprite } from './draw';
|
||||
import { setTile } from '../common/tileUtils';
|
||||
import { decodeStringFromUint8Array } from '../common/binaryUtils';
|
||||
|
||||
function log(message: string) {
|
||||
if (DEVELOPMENT && !TESTS) {
|
||||
@@ -180,7 +180,7 @@ export function handleUpdateEntity(game: PonyTownGame, update: DecodedUpdate) {
|
||||
|
||||
export function handleUpdatePonies(game: PonyTownGame, ponies: PonyData[]) {
|
||||
for (const [id, options = {}, name, info, playerState, nameBad] of ponies) {
|
||||
const decodedName = name && decodeString(name) || undefined;
|
||||
const decodedName = name && decodeStringFromUint8Array(name) || undefined;
|
||||
const filteredName = filterEntityName(game, decodedName, nameBad);
|
||||
const decodedInfo = info ? bitmask(info, PONY_INFO_KEY) : '';
|
||||
const pony = createPonyEntity(game, id, options, filteredName, decodedInfo, EntityState.None);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { BinaryWriter, getWriterBuffer, createBinaryWriter, resizeWriter } from 'ag-sockets/dist/browser';
|
||||
import { BinaryWriter, getWriterBuffer, createBinaryWriter, resizeWriter, readUint8Array, BinaryReader } from 'ag-sockets/dist/browser';
|
||||
import { isDataViewError } from './utils';
|
||||
import { encodeStringTo } from 'ag-sockets/dist/utf8';
|
||||
import { getLength } from 'ag-sockets/dist/utils';
|
||||
|
||||
export function writeBinary(write: (writer: BinaryWriter) => void): Uint8Array {
|
||||
const writer = createBinaryWriter();
|
||||
@@ -19,3 +21,153 @@ export function writeBinary(write: (writer: BinaryWriter) => void): Uint8Array {
|
||||
|
||||
return getWriterBuffer(writer);
|
||||
}
|
||||
|
||||
export function decodeString(value: DataView | null, offset: number, length: number): string | null {
|
||||
if (value == null) return null;
|
||||
|
||||
let result = '';
|
||||
const end = offset + length;
|
||||
|
||||
for (let i = offset; i < end;) {
|
||||
const byte1 = value.getUint8(i++);
|
||||
let code: number;
|
||||
|
||||
if ((byte1 & 0x80) === 0) {
|
||||
code = byte1;
|
||||
} else if ((byte1 & 0xe0) === 0xc0) {
|
||||
const byte2 = continuationByte(value, i++, end);
|
||||
code = ((byte1 & 0x1f) << 6) | byte2;
|
||||
|
||||
if (code < 0x80) {
|
||||
throw Error('Invalid continuation byte');
|
||||
}
|
||||
} else if ((byte1 & 0xf0) === 0xe0) {
|
||||
const byte2 = continuationByte(value, i++, end);
|
||||
const byte3 = continuationByte(value, i++, end);
|
||||
code = ((byte1 & 0x0f) << 12) | (byte2 << 6) | byte3;
|
||||
|
||||
if (code < 0x0800) {
|
||||
throw Error('Invalid continuation byte');
|
||||
}
|
||||
|
||||
if (code >= 0xd800 && code <= 0xdfff) {
|
||||
throw Error(`Lone surrogate U+${code.toString(16).toUpperCase()} is not a scalar value`);
|
||||
}
|
||||
} else if ((byte1 & 0xf8) === 0xf0) {
|
||||
const byte2 = continuationByte(value, i++, end);
|
||||
const byte3 = continuationByte(value, i++, end);
|
||||
const byte4 = continuationByte(value, i++, end);
|
||||
code = ((byte1 & 0x0f) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
|
||||
|
||||
if (code < 0x010000 || code > 0x10ffff) {
|
||||
throw Error('Invalid continuation byte');
|
||||
}
|
||||
} else {
|
||||
throw Error('Invalid UTF-8 detected');
|
||||
}
|
||||
|
||||
if (code > 0xffff) {
|
||||
code -= 0x10000;
|
||||
result += String.fromCharCode(code >>> 10 & 0x3ff | 0xd800);
|
||||
code = 0xdc00 | code & 0x3ff;
|
||||
}
|
||||
|
||||
result += String.fromCharCode(code);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function continuationByte(buffer: DataView, index: number, end: number): number {
|
||||
if (index >= end) throw Error('Invalid byte index');
|
||||
|
||||
const continuationByte = buffer.getUint8(index);
|
||||
|
||||
if ((continuationByte & 0xC0) === 0x80) {
|
||||
return continuationByte & 0x3F;
|
||||
} else {
|
||||
throw Error('Invalid continuation byte');
|
||||
}
|
||||
}
|
||||
|
||||
export function encodeString(string?: string | null) {
|
||||
const writer = createBinaryWriter(getStringLengthWithLength(string));
|
||||
if (string != null) {
|
||||
writeStringValue(writer, string);
|
||||
}
|
||||
return getWriterBuffer(writer);
|
||||
}
|
||||
|
||||
export function getStringLengthWithLength(value?: string | null) {
|
||||
if (value == null)
|
||||
return 1;
|
||||
const len = stringLengthInBytes(value);
|
||||
return getLength(len) + len;
|
||||
}
|
||||
|
||||
export function writeStringValue(writer: BinaryWriter, value: string) {
|
||||
writer.offset = encodeStringTo(writer.view, writer.offset, value);
|
||||
|
||||
if (writer.offset > writer.view.byteLength) {
|
||||
throw new Error('Exceeded DataView size');
|
||||
}
|
||||
}
|
||||
|
||||
function stringLengthInBytes(value: string): number {
|
||||
let result = 0;
|
||||
forEachCharacter(value, code => result += charLengthInBytes(code));
|
||||
return result;
|
||||
}
|
||||
|
||||
function forEachCharacter(value: string, callback: (code: number) => void) {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const code = value.charCodeAt(i);
|
||||
|
||||
// high surrogate
|
||||
if (code >= 0xd800 && code <= 0xdbff) {
|
||||
if ((i + 1) < value.length) {
|
||||
const extra = value.charCodeAt(i + 1);
|
||||
|
||||
// low surrogate
|
||||
if ((extra & 0xfc00) === 0xdc00) {
|
||||
i++;
|
||||
callback(((code & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function charLengthInBytes(code: number): number {
|
||||
if ((code & 0xffffff80) === 0) {
|
||||
return 1;
|
||||
} else if ((code & 0xfffff800) === 0) {
|
||||
return 2;
|
||||
} else if ((code & 0xffff0000) === 0) {
|
||||
return 3;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
export function resizeWriterWithData(writer: BinaryWriter) {
|
||||
const size = writer.view.byteLength;
|
||||
const originalBuffer = new Uint8Array(writer.view.buffer);
|
||||
const resizedBuffer = new Uint8Array(size * 2);
|
||||
for (let i = 0; i < originalBuffer.byteLength; i++) {
|
||||
resizedBuffer[i] = originalBuffer[i];
|
||||
}
|
||||
const resizedDataView = new DataView(resizedBuffer.buffer);
|
||||
writer.view = resizedDataView;
|
||||
}
|
||||
|
||||
export function decodeStringFromBuffer(reader: BinaryReader) {
|
||||
return decodeStringFromUint8Array(readUint8Array(reader));
|
||||
}
|
||||
|
||||
export function decodeStringFromUint8Array(value: Uint8Array | null) {
|
||||
const view = value ? new DataView(value.buffer, value.byteOffset, value.byteLength) : null;
|
||||
return decodeString(view, 0, view ? view.byteLength : 0);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ import {
|
||||
BinaryWriter, BinaryReader, writeInt16, readInt16, createBinaryReader, readUint16, readLength,
|
||||
readUint32, readUint8, readObject, readUint8Array
|
||||
} from 'ag-sockets/dist/browser';
|
||||
import { decodeString } from 'ag-sockets/dist/utf8';
|
||||
import { DecodedUpdate, DecodedRegionUpdate, TileUpdate, UpdateFlags } from '../interfaces';
|
||||
import { tileWidth, tileHeight, MAX_VELOCITY } from '../constants';
|
||||
import { decodeStringFromUint8Array } from '../binaryUtils';
|
||||
|
||||
export function writeVelocity(writer: BinaryWriter, value: number) {
|
||||
if (value >= MAX_VELOCITY || value <= -MAX_VELOCITY) {
|
||||
@@ -140,7 +140,7 @@ export function readOneUpdate(reader: BinaryReader): DecodedUpdate | undefined {
|
||||
}
|
||||
|
||||
if ((flags & UpdateFlags.Name) !== 0) {
|
||||
update.name = decodeString(readUint8Array(reader)) || undefined;
|
||||
update.name = decodeStringFromUint8Array(readUint8Array(reader)) || undefined;
|
||||
update.filterName = (flags & UpdateFlags.NameBad) !== 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { max, compact } from 'lodash';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { Psd, writePsd, Layer } from 'ag-psd';
|
||||
import { Psd, writePsd, Layer, BlendMode } from 'ag-psd';
|
||||
import { SpriteSet, PonyInfoNumber, PaletteSpriteSet, NoDraw } from '../../common/interfaces';
|
||||
import { times, cloneDeep, setFlag, includes, toInt } from '../../common/utils';
|
||||
import { createDefaultPony, syncLockedPonyInfoNumber, toPaletteNumber, mockPaletteManager } from '../../common/ponyInfo';
|
||||
@@ -237,7 +237,7 @@ function createPsdPatternLayers(sheet: Sheet, rows: number, cols: number, layer:
|
||||
canvas: drawPsdLayer(sheet, rows, cols, layer, i),
|
||||
hidden: true,
|
||||
clipping: true,
|
||||
blendMode: 'multiply',
|
||||
blendMode: 'multiply' as BlendMode,
|
||||
})),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { repeat } from 'lodash';
|
||||
import { toByteArray } from 'base64-js';
|
||||
import { encodeString } from 'ag-sockets/dist/utf8';
|
||||
import { PonyOptions, EntityState, UpdateFlags } from '../common/interfaces';
|
||||
import { ICharacter, IAccount, Character, queryCharacter } from './db';
|
||||
import { isForbiddenName } from '../common/security';
|
||||
@@ -23,6 +22,7 @@ import { isPonyFlying } from '../common/entityUtils';
|
||||
import { createCharacterState, updateClientCharacter } from './playerUtils';
|
||||
import { encodeExpression } from '../common/encoders/expressionEncoder';
|
||||
import { QueryFilter } from 'mongoose';
|
||||
import { encodeString } from '../common/binaryUtils';
|
||||
|
||||
export const defaultCharacterState: CharacterState = { x: 0, y: 0 };
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { resizeWriter, writeUint8, BinaryWriter, writeUint32, writeUint16 } from 'ag-sockets';
|
||||
import { encodeString } from 'ag-sockets/dist/utf8';
|
||||
import { writeUint8, BinaryWriter, writeUint32, writeUint16 } from 'ag-sockets';
|
||||
import {
|
||||
Entity, Rect, EntityState, UpdateFlags, Action, EntityOrPonyOptions, UpdateType, TileType, canWalk, setAnimationToEntityState
|
||||
} from '../common/interfaces';
|
||||
@@ -16,6 +15,7 @@ import { PONY_TYPE } from '../common/constants';
|
||||
import { grapesPurple, grapesGreen } from '../common/entities';
|
||||
import { getTile } from '../common/tileUtils';
|
||||
import { getRegion, getRegionGlobal } from '../common/region';
|
||||
import { encodeString, resizeWriterWithData } from '../common/binaryUtils';
|
||||
|
||||
export function isEntityShadowed(entity: ServerEntity): entity is ServerEntityWithClient {
|
||||
return entity.client !== undefined && entity.client.shadowed;
|
||||
@@ -163,18 +163,17 @@ export function pushUpdateEntity(update: EntityUpdateBase) {
|
||||
}
|
||||
}
|
||||
|
||||
function resizePreserveWriter(error: unknown, writer: BinaryWriter, offset: number) {
|
||||
function resizePreserveWriter(error: Error, writer: BinaryWriter, offset: number) {
|
||||
if (isOverflowError(error)) {
|
||||
const bytes = writer.bytes;
|
||||
resizeWriter(writer);
|
||||
writer.bytes.set(bytes);
|
||||
resizeWriterWithData(writer);
|
||||
writer.offset = offset;
|
||||
// DEVELOPMENT && logger.debug(`resize writer to ${writer.bytes.byteLength} (${error.message})`);
|
||||
// DEVELOPMENT && console.log(`resize writer to ${writer.view.byteLength} (${error.message})`);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function pushAddEntityToClient(client: IClient, entity: ServerEntity) {
|
||||
const writer = client.updateQueue;
|
||||
const offset = writer.offset;
|
||||
@@ -185,7 +184,7 @@ export function pushAddEntityToClient(client: IClient, entity: ServerEntity) {
|
||||
writeOneEntity(writer, entity, client);
|
||||
break;
|
||||
} catch (e) {
|
||||
resizePreserveWriter(e, writer, offset);
|
||||
resizePreserveWriter(e as Error, writer, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,7 +200,7 @@ export function pushUpdateEntityToClient(client: IClient, update: EntityUpdateBa
|
||||
writeOneUpdate(writer, entity, flags, x, y, vx, vy, options, action, playerState);
|
||||
break;
|
||||
} catch (e) {
|
||||
resizePreserveWriter(e, writer, offset);
|
||||
resizePreserveWriter(e as Error, writer, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,7 +215,7 @@ export function pushRemoveEntityToClient(client: IClient, entity: ServerEntity)
|
||||
writeUint32(writer, entity.id);
|
||||
break;
|
||||
} catch (e) {
|
||||
resizePreserveWriter(e, writer, offset);
|
||||
resizePreserveWriter(e as Error, writer, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,7 +232,7 @@ export function pushUpdateTileToClient(client: IClient, x: number, y: number, ty
|
||||
writeUint8(writer, type);
|
||||
break;
|
||||
} catch (e) {
|
||||
resizePreserveWriter(e, writer, offset);
|
||||
resizePreserveWriter(e as Error, writer, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import * as express from 'express';
|
||||
import { WebSocketServer } from '@encharm/cws';
|
||||
import { compact, once } from 'lodash';
|
||||
import { copySync, removeSync, ensureDirSync } from 'fs-extra';
|
||||
import { createServerHost, createClientOptions, ServerOptions, ClientExtensions, Packet } from 'ag-sockets';
|
||||
import { createServerHost, createClientOptions, ServerOptions, ClientExtensions } from 'ag-sockets';
|
||||
import { config, port, server, args, version } from './config';
|
||||
import { YEAR, WEEK } from '../common/constants';
|
||||
import { rollbarCheckIgnore } from '../common/rollbar';
|
||||
@@ -210,7 +210,7 @@ const sessionMiddlewares = once(() => [createSession(), passport.initialize(), p
|
||||
const adminMiddlewares = once(() => [...sessionMiddlewares(), isAdmin(server)]);
|
||||
const socketOptionsBase: ServerOptions = {
|
||||
ws: { Server: WebSocketServer },
|
||||
hash: STAMP,
|
||||
hash: STAMP.toString(),
|
||||
};
|
||||
|
||||
initLogRequest(stats.logRequest);
|
||||
@@ -246,15 +246,15 @@ if (args.game) {
|
||||
...socketOptionsBase,
|
||||
verifyClient: () => !getSettings().isServerOffline && !liveSettings.shutdown,
|
||||
forceBinary: true,
|
||||
onSend: (packet: Packet) => {
|
||||
sent += packet.binary ? packet.binary.byteLength : (packet.json ? packet.json.length : 0);
|
||||
onSend: (id: number, name: string, packetSize: number, binary: boolean) => {
|
||||
sent += packetSize;
|
||||
sentPackets++;
|
||||
stats.logSendStats(packet);
|
||||
stats.logSendStats(id, name, binary, packetSize);
|
||||
},
|
||||
onRecv: (packet: Packet) => {
|
||||
received += packet.binary ? packet.binary.byteLength : (packet.json ? packet.json.length : 0);
|
||||
onRecv: (id: number, name: string, packetSize: number, binary: boolean) => {
|
||||
received += packetSize;
|
||||
receivedPackets++;
|
||||
stats.logRecvStats(packet);
|
||||
stats.logRecvStats(id, name, binary, packetSize);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export function toFriendRemove(client: IClient): FriendStatusData {
|
||||
}
|
||||
|
||||
export function toFriend(client: IClient): FriendStatusData {
|
||||
if (client.isConnected) {
|
||||
if (client.isConnected()) {
|
||||
return toFriendOnline(client);
|
||||
} else {
|
||||
return toFriendOffline(client);
|
||||
|
||||
@@ -3,7 +3,6 @@ import * as path from 'path';
|
||||
import * as moment from 'moment';
|
||||
import { compact } from 'lodash';
|
||||
import { Request } from 'express';
|
||||
import { Packet } from 'ag-sockets';
|
||||
import { RequestStats, ServerStats } from '../common/adminInterfaces';
|
||||
import { HOUR } from '../common/constants';
|
||||
import { ByteSize } from './utils/byteSize';
|
||||
@@ -92,13 +91,13 @@ export class StatsTracker {
|
||||
logSpamming = () => {
|
||||
this.dailySpamming++;
|
||||
}
|
||||
logRecvStats = (packet: Packet) => {
|
||||
this.logSocketStats(this.recvStats, packet);
|
||||
logRecvStats = (id: number, name: string, binary: boolean, size: number) => {
|
||||
this.logSocketStats(this.recvStats, id, name, binary, size);
|
||||
}
|
||||
logSendStats = (packet: Packet) => {
|
||||
this.logSocketStats(this.sendStats, packet);
|
||||
logSendStats = (id: number, name: string, binary: boolean, size: number) => {
|
||||
this.logSocketStats(this.sendStats, id, name, binary, size);
|
||||
}
|
||||
private logSocketStats(stats: (SocketStats | undefined)[], { id, name, binary, json }: Packet) {
|
||||
private logSocketStats(stats: (SocketStats | undefined)[], id: number, name: string, binary: boolean, size: number) {
|
||||
const entry = stats[id] || (stats[id] = {
|
||||
id,
|
||||
name,
|
||||
@@ -119,7 +118,7 @@ export class StatsTracker {
|
||||
entry.countStr++;
|
||||
}
|
||||
|
||||
entry.size.addBytes(binary ? (binary.length || binary.byteLength) : (json ? json.length : 0));
|
||||
entry.size.addBytes(size);
|
||||
}
|
||||
getStats(): RequestStats[] {
|
||||
const result: RequestStats[] = [];
|
||||
|
||||
@@ -95,7 +95,7 @@ export class World {
|
||||
// this.mapPools.set('house', createPool(10, () => createHouseMap(this, true), resetHouseMap));
|
||||
|
||||
partyService.partyChanged.subscribe(client => {
|
||||
if (client.isConnected && client.map.usage === MapUsage.Party) {
|
||||
if (client.isConnected() && client.map.usage === MapUsage.Party) {
|
||||
if (
|
||||
client.party && client.party.leader === client && client.map.instance === client.accountId &&
|
||||
!this.maps.some(m => m.id === client.map.id && m.instance === client.party!.id)
|
||||
@@ -785,7 +785,7 @@ export class World {
|
||||
client.disconnect(true);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
if (client.isConnected) {
|
||||
if (client.isConnected()) {
|
||||
client.disconnect(true);
|
||||
}
|
||||
}, 200);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { stubClass, resetStubMethods } from '../lib';
|
||||
import { NgZone } from '@angular/core';
|
||||
import { encodeString } from 'ag-sockets/dist/utf8';
|
||||
import { Subject } from 'rxjs';
|
||||
import { expect } from 'chai';
|
||||
import { stub, assert, SinonStub } from 'sinon';
|
||||
@@ -25,6 +24,7 @@ import { createServerRegion } from '../../server/serverRegion';
|
||||
import { ServerRegion } from '../../server/serverInterfaces';
|
||||
import { getTile } from '../../common/tileUtils';
|
||||
import { Weather } from '../../common/commonInterfaces';
|
||||
import { encodeString } from '../../common/binaryUtils';
|
||||
|
||||
describe('ClientActions', () => {
|
||||
let zone: NgZone;
|
||||
|
||||
@@ -3,13 +3,13 @@ import { expect } from 'chai';
|
||||
import { encodeUpdateSimple, encodeRegionSimple } from '../../../common/encoders/updateEncoder';
|
||||
import { EntityState, DecodedRegionUpdate, UpdateFlags, TileType } from '../../../common/interfaces';
|
||||
import { entity, mockClient, serverEntity } from '../../mocks';
|
||||
import { encodeString } from 'ag-sockets/dist/utf8';
|
||||
import { emptyUpdate, decodeUpdate } from '../../../common/encoders/updateDecoder';
|
||||
import { createServerRegion } from '../../../server/serverRegion';
|
||||
import { IClient, ServerRegion } from '../../../server/serverInterfaces';
|
||||
import { setEntityName } from '../../../server/entityUtils';
|
||||
import { compressTiles } from '../../../common/compress';
|
||||
import { REGION_SIZE } from '../../../common/constants';
|
||||
import { encodeString } from '../../../common/binaryUtils';
|
||||
|
||||
describe('updateEncoder', () => {
|
||||
describe('encodeUpdate() + decodeUpdate()', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import '../lib';
|
||||
import { expect } from 'chai';
|
||||
import { encodeString } from 'ag-sockets/dist/utf8';
|
||||
import { createExtraOptions, updatePony, encryptInfo, createPony, getAndFixCharacterState } from '../../server/characterUtils';
|
||||
import { account, character, serverEntity, entity, genObjectId } from '../mocks';
|
||||
import { CharacterFlags, CharacterState, SupporterFlags, CharacterStateFlags } from '../../common/adminInterfaces';
|
||||
@@ -13,6 +12,7 @@ import { CounterService } from '../../server/services/counter';
|
||||
import { createCharacterState } from '../../server/playerUtils';
|
||||
import { hasFlag } from '../../common/utils';
|
||||
import { Types } from 'mongoose';
|
||||
import { encodeString } from '../../common/binaryUtils';
|
||||
|
||||
describe('characterUtils', () => {
|
||||
describe('createPony()', () => {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { expect } from 'chai';
|
||||
import { stub, assert, spy, SinonSpy, SinonFakeTimers, useFakeTimers, SinonStub } from 'sinon';
|
||||
import { range } from 'lodash';
|
||||
import { getWriterBuffer } from 'ag-sockets';
|
||||
import { encodeString } from 'ag-sockets/dist/utf8';
|
||||
import {
|
||||
ChatType, TileType, Action, PlayerAction, ModAction, Eye, Muzzle, SelectFlags, InfoFlags
|
||||
} from '../../common/interfaces';
|
||||
@@ -24,6 +23,7 @@ import { SupporterInvitesService } from '../../server/services/supporterInvites'
|
||||
import { createCamera } from '../../common/camera';
|
||||
import { FriendsService } from '../../server/services/friends';
|
||||
import * as playerUtils from '../../server/playerUtils';
|
||||
import { encodeString } from '../../common/binaryUtils';
|
||||
|
||||
describe('ServerActions', () => {
|
||||
let accountService = stubFromInstance<AccountService>({
|
||||
|
||||
Reference in New Issue
Block a user