New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

att-client

Package Overview
Dependencies
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

att-client - npm Package Compare versions

Comparing version 0.5.1 to 0.5.2-beta.1

3

dist/cjs/Client/Client.js

@@ -97,2 +97,3 @@ "use strict";

logVerbosity: configuredLogVerbosity,
maxMissedServerHeartbeats: config.maxMissedServerHeartbeats ?? constants_js_1.DEFAULTS.maxMissedServerHeartbeats,
maxSubscriptionsPerWebSocket: config.maxSubscriptionsPerWebSocket ?? constants_js_1.DEFAULTS.maxSubscriptionsPerWebSocket,

@@ -102,3 +103,3 @@ maxWorkerConcurrency: config.maxWorkerConcurrency ?? constants_js_1.DEFAULTS.maxWorkerConcurrency,

serverConnectionRecoveryDelay: config.serverConnectionRecoveryDelay ?? constants_js_1.DEFAULTS.serverConnectionRecoveryDelay,
serverHeartbeatTimeout: config.serverHeartbeatTimeout ?? constants_js_1.DEFAULTS.serverHeartbeatTimeout,
serverHeartbeatInterval: config.serverHeartbeatInterval ?? constants_js_1.DEFAULTS.serverHeartbeatInterval,
supportedServerFleets: config.supportedServerFleets ?? constants_js_1.DEFAULTS.supportedServerFleets,

@@ -105,0 +106,0 @@ tokenUrl: config.tokenUrl ?? constants_js_1.DEFAULTS.tokenUrl,

@@ -7,12 +7,13 @@ "use strict";

name: 'att-client',
version: '0.5.1'
version: '0.5.2-beta.1'
};
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const MAX_MISSED_SERVER_HEARTBEATS = 3;
const MAX_SUBSCRIPTIONS_PER_WEBSOCKET = 500;
const MAX_WORKER_CONCURRENCY = 5;
const MAX_SUBSCRIPTIONS_PER_WEBSOCKET = 500;
exports.MAX_WORKER_CONCURRENCY_WARNING = 10;
const REST_BASE_URL = 'https://webapi.townshiptale.com/api';
const SERVER_CONNECTION_RECOVERY_DELAY = 10 * SECOND;
const SERVER_HEARTBEAT_TIMEOUT = 10 * MINUTE;
const SERVER_HEARTBEAT_INTERVAL = 20 * SECOND;
const SUPPORTED_SERVER_FLEETS = ['att-release', 'att-quest'];

@@ -37,6 +38,7 @@ const TOKEN_URL = 'https://accounts.townshiptale.com/connect/token';

restBaseUrl: REST_BASE_URL,
maxMissedServerHeartbeats: MAX_MISSED_SERVER_HEARTBEATS,
maxSubscriptionsPerWebSocket: MAX_SUBSCRIPTIONS_PER_WEBSOCKET,
maxWorkerConcurrency: MAX_WORKER_CONCURRENCY,
maxSubscriptionsPerWebSocket: MAX_SUBSCRIPTIONS_PER_WEBSOCKET,
serverConnectionRecoveryDelay: SERVER_CONNECTION_RECOVERY_DELAY,
serverHeartbeatTimeout: SERVER_HEARTBEAT_TIMEOUT,
serverHeartbeatInterval: SERVER_HEARTBEAT_INTERVAL,
supportedServerFleets: SUPPORTED_SERVER_FLEETS,

@@ -43,0 +45,0 @@ tokenUrl: TOKEN_URL,

@@ -14,2 +14,4 @@ "use strict";

servers;
keepAlive;
missedHeartbeats;
userId;

@@ -21,2 +23,4 @@ constructor(client, group, member) {

this.id = group.id;
this.keepAlive = undefined;
this.missedHeartbeats = 0;
this.name = group.name ?? '';

@@ -75,2 +79,12 @@ this.permissions = this.getPermissions(group, member);

}),
this.client.subscriptions.subscribe('group-server-heartbeat', this.id.toString(), async (message) => {
try {
const status = message.content;
this.client.logger.debug(`Heartbeat for server ${status.id} (${status.name}).`, JSON.stringify(status));
this.handleHeartbeat(status);
}
catch (error) {
this.client.logger.error(`Error while handling server heartbeat: ${error.message}`);
}
}),
this.client.subscriptions.subscribe('group-server-create', this.id.toString(), _unstableMessage => {

@@ -137,2 +151,22 @@ try {

}
async handleHeartbeat(status) {
if (status.is_online) {
this.missedHeartbeats = 0;
clearTimeout(this.keepAlive);
this.keepAlive = setInterval(() => {
const serverId = status.id;
const server = this.servers[serverId];
if (typeof server === 'undefined') {
this.client.logger.error(`Server ${serverId} not found in group ${this.id} (${this.name}).`);
return;
}
this.client.logger.info(`No heartbeat received for server ${serverId} (${server.name}) in the last ${this.client.config.serverHeartbeatInterval * ++this.missedHeartbeats} ms.`);
if (this.missedHeartbeats >= this.client.config.maxMissedServerHeartbeats) {
this.client.logger.info(`Maximum missed heartbeats reached for server ${serverId} (${server.name}). Closing connection.`);
server.disconnect();
}
}, this.client.config.serverHeartbeatInterval);
}
this.manageServerConnection(status);
}
async manageServerConnection(status) {

@@ -148,5 +182,3 @@ const serverId = status.id;

const mayConnect = hasConsolePermission && isSupportedServerFleet;
const lastHeartbeatAt = +new Date(status.online_ping ?? '2022-06-01T00:00:00.000Z');
const timeSinceLastHeartbeat = Date.now() - lastHeartbeatAt;
const isServerOnline = timeSinceLastHeartbeat < this.client.config.serverHeartbeatTimeout;
const isServerOnline = status.is_online;
const hasOnlinePlayers = status.online_players.length > 0;

@@ -153,0 +185,0 @@ if (server.status === 'disconnected' && mayConnect && isServerOnline && hasOnlinePlayers) {

@@ -85,6 +85,6 @@ "use strict";

if (typeof message.content === 'undefined') {
that.client.logger.error(`Received a message with ID ${message.id} but no content.`, JSON.stringify(message));
that.client.logger.error(`Received a message with ID ${that.instanceId}-${message.id} but no content.`, JSON.stringify(message));
return;
}
that.client.logger.debug(`Received ${message.event} message with ID ${message.id}.`, JSON.stringify(message));
that.client.logger.debug(`Received ${message.event} message with ID ${that.instanceId}-${message.id}.`, JSON.stringify(message));
const eventName = message.id === 0 ? `${message.event}/${message.key}` : `message-${message.id}`;

@@ -91,0 +91,0 @@ that.events.emit(eventName, {

@@ -91,2 +91,3 @@ import { createHash } from 'node:crypto';

logVerbosity: configuredLogVerbosity,
maxMissedServerHeartbeats: config.maxMissedServerHeartbeats ?? DEFAULTS.maxMissedServerHeartbeats,
maxSubscriptionsPerWebSocket: config.maxSubscriptionsPerWebSocket ?? DEFAULTS.maxSubscriptionsPerWebSocket,

@@ -96,3 +97,3 @@ maxWorkerConcurrency: config.maxWorkerConcurrency ?? DEFAULTS.maxWorkerConcurrency,

serverConnectionRecoveryDelay: config.serverConnectionRecoveryDelay ?? DEFAULTS.serverConnectionRecoveryDelay,
serverHeartbeatTimeout: config.serverHeartbeatTimeout ?? DEFAULTS.serverHeartbeatTimeout,
serverHeartbeatInterval: config.serverHeartbeatInterval ?? DEFAULTS.serverHeartbeatInterval,
supportedServerFleets: config.supportedServerFleets ?? DEFAULTS.supportedServerFleets,

@@ -99,0 +100,0 @@ tokenUrl: config.tokenUrl ?? DEFAULTS.tokenUrl,

import './Logger/index.js';
export const AGENT = {
name: 'att-client',
version: '0.5.1'
version: '0.5.2-beta.1'
};
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const MAX_MISSED_SERVER_HEARTBEATS = 3;
const MAX_SUBSCRIPTIONS_PER_WEBSOCKET = 500;
const MAX_WORKER_CONCURRENCY = 5;
const MAX_SUBSCRIPTIONS_PER_WEBSOCKET = 500;
export const MAX_WORKER_CONCURRENCY_WARNING = 10;
const REST_BASE_URL = 'https://webapi.townshiptale.com/api';
const SERVER_CONNECTION_RECOVERY_DELAY = 10 * SECOND;
const SERVER_HEARTBEAT_TIMEOUT = 10 * MINUTE;
const SERVER_HEARTBEAT_INTERVAL = 20 * SECOND;
const SUPPORTED_SERVER_FLEETS = ['att-release', 'att-quest'];

@@ -33,6 +34,7 @@ const TOKEN_URL = 'https://accounts.townshiptale.com/connect/token';

restBaseUrl: REST_BASE_URL,
maxMissedServerHeartbeats: MAX_MISSED_SERVER_HEARTBEATS,
maxSubscriptionsPerWebSocket: MAX_SUBSCRIPTIONS_PER_WEBSOCKET,
maxWorkerConcurrency: MAX_WORKER_CONCURRENCY,
maxSubscriptionsPerWebSocket: MAX_SUBSCRIPTIONS_PER_WEBSOCKET,
serverConnectionRecoveryDelay: SERVER_CONNECTION_RECOVERY_DELAY,
serverHeartbeatTimeout: SERVER_HEARTBEAT_TIMEOUT,
serverHeartbeatInterval: SERVER_HEARTBEAT_INTERVAL,
supportedServerFleets: SUPPORTED_SERVER_FLEETS,

@@ -39,0 +41,0 @@ tokenUrl: TOKEN_URL,

@@ -11,2 +11,4 @@ import { TypedEmitter } from '@mdingena/tiny-typed-emitter';

servers;
keepAlive;
missedHeartbeats;
userId;

@@ -18,2 +20,4 @@ constructor(client, group, member) {

this.id = group.id;
this.keepAlive = undefined;
this.missedHeartbeats = 0;
this.name = group.name ?? '';

@@ -72,2 +76,12 @@ this.permissions = this.getPermissions(group, member);

}),
this.client.subscriptions.subscribe('group-server-heartbeat', this.id.toString(), async (message) => {
try {
const status = message.content;
this.client.logger.debug(`Heartbeat for server ${status.id} (${status.name}).`, JSON.stringify(status));
this.handleHeartbeat(status);
}
catch (error) {
this.client.logger.error(`Error while handling server heartbeat: ${error.message}`);
}
}),
this.client.subscriptions.subscribe('group-server-create', this.id.toString(), _unstableMessage => {

@@ -134,2 +148,22 @@ try {

}
async handleHeartbeat(status) {
if (status.is_online) {
this.missedHeartbeats = 0;
clearTimeout(this.keepAlive);
this.keepAlive = setInterval(() => {
const serverId = status.id;
const server = this.servers[serverId];
if (typeof server === 'undefined') {
this.client.logger.error(`Server ${serverId} not found in group ${this.id} (${this.name}).`);
return;
}
this.client.logger.info(`No heartbeat received for server ${serverId} (${server.name}) in the last ${this.client.config.serverHeartbeatInterval * ++this.missedHeartbeats} ms.`);
if (this.missedHeartbeats >= this.client.config.maxMissedServerHeartbeats) {
this.client.logger.info(`Maximum missed heartbeats reached for server ${serverId} (${server.name}). Closing connection.`);
server.disconnect();
}
}, this.client.config.serverHeartbeatInterval);
}
this.manageServerConnection(status);
}
async manageServerConnection(status) {

@@ -145,5 +179,3 @@ const serverId = status.id;

const mayConnect = hasConsolePermission && isSupportedServerFleet;
const lastHeartbeatAt = +new Date(status.online_ping ?? '2022-06-01T00:00:00.000Z');
const timeSinceLastHeartbeat = Date.now() - lastHeartbeatAt;
const isServerOnline = timeSinceLastHeartbeat < this.client.config.serverHeartbeatTimeout;
const isServerOnline = status.is_online;
const hasOnlinePlayers = status.online_players.length > 0;

@@ -150,0 +182,0 @@ if (server.status === 'disconnected' && mayConnect && isServerOnline && hasOnlinePlayers) {

@@ -82,6 +82,6 @@ import { EventEmitter } from 'node:events';

if (typeof message.content === 'undefined') {
that.client.logger.error(`Received a message with ID ${message.id} but no content.`, JSON.stringify(message));
that.client.logger.error(`Received a message with ID ${that.instanceId}-${message.id} but no content.`, JSON.stringify(message));
return;
}
that.client.logger.debug(`Received ${message.event} message with ID ${message.id}.`, JSON.stringify(message));
that.client.logger.debug(`Received ${message.event} message with ID ${that.instanceId}-${message.id}.`, JSON.stringify(message));
const eventName = message.id === 0 ? `${message.event}/${message.key}` : `message-${message.id}`;

@@ -88,0 +88,0 @@ that.events.emit(eventName, {

@@ -6,2 +6,3 @@ type ServerOnlinePlayers = {

export type ServerFleet = 'att-release' | 'att-quest';
type JoinType = 'PrivateGroup' | 'Public' | 'OpenGroup' | 'SupporterOnly' | 'WorldInstance' | 'PublicGroup';
export type ServerInfo = {

@@ -27,3 +28,9 @@ id: number;

up_time: string;
join_type: JoinType;
player_count: number;
player_limit: number;
created_at: string;
is_online: boolean;
transport_system: number;
};
export {};

@@ -10,2 +10,3 @@ import type { ServerFleet } from '../Api/index.js';

logVerbosity?: Verbosity;
maxMissedServerHeartbeats?: number;
maxSubscriptionsPerWebSocket?: number;

@@ -15,3 +16,3 @@ maxWorkerConcurrency?: number;

serverConnectionRecoveryDelay?: number;
serverHeartbeatTimeout?: number;
serverHeartbeatInterval?: number;
supportedServerFleets?: ServerFleet[];

@@ -18,0 +19,0 @@ tokenUrl?: string;

@@ -23,2 +23,4 @@ import type { GroupInfo, GroupMemberInfo } from '../Api/schemas/index.js';

servers: Servers;
private keepAlive;
private missedHeartbeats;
private userId;

@@ -32,2 +34,3 @@ constructor(client: Client, group: GroupInfo, member: GroupMemberInfo);

private getPermissions;
private handleHeartbeat;
private manageServerConnection;

@@ -34,0 +37,0 @@ private addServers;

@@ -1,1 +0,1 @@

export type ClientEvent = 'group-member-update' | 'group-server-create' | 'group-server-delete' | 'group-server-status' | 'group-server-update' | 'group-update' | 'me-group-create' | 'me-group-delete' | 'me-group-invite-create' | 'me-group-invite-delete';
export type ClientEvent = 'group-member-update' | 'group-server-create' | 'group-server-delete' | 'group-server-heartbeat' | 'group-server-status' | 'group-server-update' | 'group-update' | 'me-group-create' | 'me-group-delete' | 'me-group-invite-create' | 'me-group-invite-delete';

@@ -12,2 +12,5 @@ import type { GroupInfo, GroupMemberInfo, ServerInfo } from '../Api/schemas/index.js';

};
type GroupServerHeartbeatMessage = EventMessage<'group-server-heartbeat'> & {
content: ServerInfo;
};
type GroupServerStatusMessage = EventMessage<'group-server-status'> & {

@@ -37,3 +40,3 @@ content: ServerInfo;

};
type ClientEventMessageUnion = GroupMemberUpdateMessage | GroupServerStatusMessage | GroupUpdateMessage | MeGroupCreateMessage | MeGroupDeleteMessage | MeGroupInviteCreateMessage | MeGroupInviteDeleteMessage;
type ClientEventMessageUnion = GroupMemberUpdateMessage | GroupServerHeartbeatMessage | GroupServerStatusMessage | GroupUpdateMessage | MeGroupCreateMessage | MeGroupDeleteMessage | MeGroupInviteCreateMessage | MeGroupInviteDeleteMessage;
export type ClientEventMessage<T> = Extract<ClientEventMessageUnion, {

@@ -40,0 +43,0 @@ event: T;

@@ -33,3 +33,3 @@ import type { Client } from '../Client/index.js';

} & {
key: "POST /ws/subscription/group-member-update" | "POST /ws/subscription/group-server-status" | "POST /ws/subscription/group-update" | "POST /ws/subscription/me-group-create" | "POST /ws/subscription/me-group-delete" | "POST /ws/subscription/me-group-invite-create" | "POST /ws/subscription/me-group-invite-delete" | "POST /ws/subscription/group-server-create" | "POST /ws/subscription/group-server-delete" | "POST /ws/subscription/group-server-update";
key: "POST /ws/subscription/group-member-update" | "POST /ws/subscription/group-server-heartbeat" | "POST /ws/subscription/group-server-status" | "POST /ws/subscription/group-update" | "POST /ws/subscription/me-group-create" | "POST /ws/subscription/me-group-delete" | "POST /ws/subscription/me-group-invite-create" | "POST /ws/subscription/me-group-invite-delete" | "POST /ws/subscription/group-server-create" | "POST /ws/subscription/group-server-delete" | "POST /ws/subscription/group-server-update";
content: "";

@@ -42,3 +42,3 @@ })> | undefined;

} & {
key: "DELETE /ws/subscription/group-member-update" | "DELETE /ws/subscription/group-server-status" | "DELETE /ws/subscription/group-update" | "DELETE /ws/subscription/me-group-create" | "DELETE /ws/subscription/me-group-delete" | "DELETE /ws/subscription/me-group-invite-create" | "DELETE /ws/subscription/me-group-invite-delete" | "DELETE /ws/subscription/group-server-create" | "DELETE /ws/subscription/group-server-delete" | "DELETE /ws/subscription/group-server-update";
key: "DELETE /ws/subscription/group-member-update" | "DELETE /ws/subscription/group-server-heartbeat" | "DELETE /ws/subscription/group-server-status" | "DELETE /ws/subscription/group-update" | "DELETE /ws/subscription/me-group-create" | "DELETE /ws/subscription/me-group-delete" | "DELETE /ws/subscription/me-group-invite-create" | "DELETE /ws/subscription/me-group-invite-delete" | "DELETE /ws/subscription/group-server-create" | "DELETE /ws/subscription/group-server-delete" | "DELETE /ws/subscription/group-server-update";
content: "";

@@ -45,0 +45,0 @@ })> | undefined;

@@ -17,3 +17,3 @@ import type { ClientEvent } from '../Subscriptions/ClientEvent.js';

} & {
key: "POST /ws/subscription/group-member-update" | "POST /ws/subscription/group-server-status" | "POST /ws/subscription/group-update" | "POST /ws/subscription/me-group-create" | "POST /ws/subscription/me-group-delete" | "POST /ws/subscription/me-group-invite-create" | "POST /ws/subscription/me-group-invite-delete" | "POST /ws/subscription/group-server-create" | "POST /ws/subscription/group-server-delete" | "POST /ws/subscription/group-server-update";
key: "POST /ws/subscription/group-member-update" | "POST /ws/subscription/group-server-heartbeat" | "POST /ws/subscription/group-server-status" | "POST /ws/subscription/group-update" | "POST /ws/subscription/me-group-create" | "POST /ws/subscription/me-group-delete" | "POST /ws/subscription/me-group-invite-create" | "POST /ws/subscription/me-group-invite-delete" | "POST /ws/subscription/group-server-create" | "POST /ws/subscription/group-server-delete" | "POST /ws/subscription/group-server-update";
content: "";

@@ -26,3 +26,3 @@ })>;

} & {
key: "DELETE /ws/subscription/group-member-update" | "DELETE /ws/subscription/group-server-status" | "DELETE /ws/subscription/group-update" | "DELETE /ws/subscription/me-group-create" | "DELETE /ws/subscription/me-group-delete" | "DELETE /ws/subscription/me-group-invite-create" | "DELETE /ws/subscription/me-group-invite-delete" | "DELETE /ws/subscription/group-server-create" | "DELETE /ws/subscription/group-server-delete" | "DELETE /ws/subscription/group-server-update";
key: "DELETE /ws/subscription/group-member-update" | "DELETE /ws/subscription/group-server-heartbeat" | "DELETE /ws/subscription/group-server-status" | "DELETE /ws/subscription/group-update" | "DELETE /ws/subscription/me-group-create" | "DELETE /ws/subscription/me-group-delete" | "DELETE /ws/subscription/me-group-invite-create" | "DELETE /ws/subscription/me-group-invite-delete" | "DELETE /ws/subscription/group-server-create" | "DELETE /ws/subscription/group-server-delete" | "DELETE /ws/subscription/group-server-update";
content: "";

@@ -29,0 +29,0 @@ })>;

{
"name": "att-client",
"version": "0.5.1",
"version": "0.5.2-beta.1",
"description": "Node bot library for A Township Tale, a VR game by Alta",

@@ -20,3 +20,2 @@ "homepage": "https://github.com/mdingena/att-client#readme",

"scripts": {
"test": "node --loader ts-node/esm -r dotenv/config test.ts",
"lint": "eslint \"src/**/*\"",

@@ -23,0 +22,0 @@ "compile": "tsc --noEmit",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc