@takaro/gameserver 0.0.0-next.0da151e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +36 -0
  2. package/dist/TakaroEmitter.d.ts +30 -0
  3. package/dist/TakaroEmitter.d.ts.map +1 -0
  4. package/dist/TakaroEmitter.js +101 -0
  5. package/dist/TakaroEmitter.js.map +1 -0
  6. package/dist/config.d.ts +9 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +13 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/gameservers/7d2d/apiResponses.d.ts +194 -0
  11. package/dist/gameservers/7d2d/apiResponses.d.ts.map +1 -0
  12. package/dist/gameservers/7d2d/apiResponses.js +2 -0
  13. package/dist/gameservers/7d2d/apiResponses.js.map +1 -0
  14. package/dist/gameservers/7d2d/connectionInfo.d.ts +38 -0
  15. package/dist/gameservers/7d2d/connectionInfo.d.ts.map +1 -0
  16. package/dist/gameservers/7d2d/connectionInfo.js +66 -0
  17. package/dist/gameservers/7d2d/connectionInfo.js.map +1 -0
  18. package/dist/gameservers/7d2d/emitter.d.ts +32 -0
  19. package/dist/gameservers/7d2d/emitter.d.ts.map +1 -0
  20. package/dist/gameservers/7d2d/emitter.js +273 -0
  21. package/dist/gameservers/7d2d/emitter.js.map +1 -0
  22. package/dist/gameservers/7d2d/index.d.ts +34 -0
  23. package/dist/gameservers/7d2d/index.d.ts.map +1 -0
  24. package/dist/gameservers/7d2d/index.js +304 -0
  25. package/dist/gameservers/7d2d/index.js.map +1 -0
  26. package/dist/gameservers/7d2d/itemWorker.d.ts +2 -0
  27. package/dist/gameservers/7d2d/itemWorker.d.ts.map +1 -0
  28. package/dist/gameservers/7d2d/itemWorker.js +36 -0
  29. package/dist/gameservers/7d2d/itemWorker.js.map +1 -0
  30. package/dist/gameservers/7d2d/items-7d2d.json +25051 -0
  31. package/dist/gameservers/7d2d/sdtdAPIClient.d.ts +19 -0
  32. package/dist/gameservers/7d2d/sdtdAPIClient.d.ts.map +1 -0
  33. package/dist/gameservers/7d2d/sdtdAPIClient.js +57 -0
  34. package/dist/gameservers/7d2d/sdtdAPIClient.js.map +1 -0
  35. package/dist/gameservers/generic/connectionInfo.d.ts +16 -0
  36. package/dist/gameservers/generic/connectionInfo.d.ts.map +1 -0
  37. package/dist/gameservers/generic/connectionInfo.js +29 -0
  38. package/dist/gameservers/generic/connectionInfo.js.map +1 -0
  39. package/dist/gameservers/generic/connectorClient.d.ts +7 -0
  40. package/dist/gameservers/generic/connectorClient.d.ts.map +1 -0
  41. package/dist/gameservers/generic/connectorClient.js +60 -0
  42. package/dist/gameservers/generic/connectorClient.js.map +1 -0
  43. package/dist/gameservers/generic/emitter.d.ts +13 -0
  44. package/dist/gameservers/generic/emitter.d.ts.map +1 -0
  45. package/dist/gameservers/generic/emitter.js +31 -0
  46. package/dist/gameservers/generic/emitter.js.map +1 -0
  47. package/dist/gameservers/generic/index.d.ts +36 -0
  48. package/dist/gameservers/generic/index.d.ts.map +1 -0
  49. package/dist/gameservers/generic/index.js +170 -0
  50. package/dist/gameservers/generic/index.js.map +1 -0
  51. package/dist/gameservers/rust/connectionInfo.d.ts +29 -0
  52. package/dist/gameservers/rust/connectionInfo.d.ts.map +1 -0
  53. package/dist/gameservers/rust/connectionInfo.js +51 -0
  54. package/dist/gameservers/rust/connectionInfo.js.map +1 -0
  55. package/dist/gameservers/rust/emitter.d.ts +32 -0
  56. package/dist/gameservers/rust/emitter.d.ts.map +1 -0
  57. package/dist/gameservers/rust/emitter.js +160 -0
  58. package/dist/gameservers/rust/emitter.js.map +1 -0
  59. package/dist/gameservers/rust/index.d.ts +35 -0
  60. package/dist/gameservers/rust/index.d.ts.map +1 -0
  61. package/dist/gameservers/rust/index.js +217 -0
  62. package/dist/gameservers/rust/index.js.map +1 -0
  63. package/dist/gameservers/rust/items-rust.json +20771 -0
  64. package/dist/getGame.d.ts +10 -0
  65. package/dist/getGame.d.ts.map +1 -0
  66. package/dist/getGame.js +27 -0
  67. package/dist/getGame.js.map +1 -0
  68. package/dist/interfaces/GameServer.d.ts +99 -0
  69. package/dist/interfaces/GameServer.d.ts.map +1 -0
  70. package/dist/interfaces/GameServer.js +235 -0
  71. package/dist/interfaces/GameServer.js.map +1 -0
  72. package/dist/main.d.ts +12 -0
  73. package/dist/main.d.ts.map +1 -0
  74. package/dist/main.js +12 -0
  75. package/dist/main.js.map +1 -0
  76. package/package.json +16 -0
  77. package/src/TakaroEmitter.ts +146 -0
  78. package/src/TakaroEmitter.unit.test.ts +201 -0
  79. package/src/__tests__/gameEventEmitter.test.ts +29 -0
  80. package/src/config.ts +20 -0
  81. package/src/gameservers/7d2d/__tests__/7d2dActions.unit.test.ts +96 -0
  82. package/src/gameservers/7d2d/__tests__/7d2dEventDetection.unit.test.ts +424 -0
  83. package/src/gameservers/7d2d/apiResponses.ts +213 -0
  84. package/src/gameservers/7d2d/connectionInfo.ts +46 -0
  85. package/src/gameservers/7d2d/emitter.ts +334 -0
  86. package/src/gameservers/7d2d/emitter.unit.test.ts +117 -0
  87. package/src/gameservers/7d2d/index.ts +367 -0
  88. package/src/gameservers/7d2d/itemWorker.ts +41 -0
  89. package/src/gameservers/7d2d/items-7d2d.json +25051 -0
  90. package/src/gameservers/7d2d/sdtdAPIClient.ts +82 -0
  91. package/src/gameservers/generic/connectionInfo.ts +19 -0
  92. package/src/gameservers/generic/connectorClient.ts +73 -0
  93. package/src/gameservers/generic/emitter.ts +36 -0
  94. package/src/gameservers/generic/index.ts +193 -0
  95. package/src/gameservers/rust/__tests__/rustActions.unit.test.ts +141 -0
  96. package/src/gameservers/rust/connectionInfo.ts +35 -0
  97. package/src/gameservers/rust/emitter.ts +198 -0
  98. package/src/gameservers/rust/emitter.unit.test.ts +95 -0
  99. package/src/gameservers/rust/index.ts +270 -0
  100. package/src/gameservers/rust/items-rust.json +20771 -0
  101. package/src/getGame.ts +34 -0
  102. package/src/interfaces/GameServer.ts +215 -0
  103. package/src/main.ts +16 -0
  104. package/tsconfig.build.json +9 -0
  105. package/tsconfig.json +9 -0
  106. package/typedoc.json +3 -0
@@ -0,0 +1,10 @@
1
+ import { GameServerOutputDTOTypeEnum, Settings } from '@takaro/apiclient';
2
+ import { IGameServer } from './interfaces/GameServer.js';
3
+ export declare enum GAME_SERVER_TYPE {
4
+ 'SEVENDAYSTODIE' = "SEVENDAYSTODIE",
5
+ 'RUST' = "RUST",
6
+ 'GENERIC' = "GENERIC",
7
+ 'MOCK' = "MOCK"
8
+ }
9
+ export declare function getGame(type: GAME_SERVER_TYPE | GameServerOutputDTOTypeEnum, connectionInfo: Record<string, unknown>, settings: Partial<Settings>, gameServerId: string): Promise<IGameServer>;
10
+ //# sourceMappingURL=getGame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getGame.d.ts","sourceRoot":"","sources":["../src/getGame.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,2BAA2B,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAK1E,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAIzD,oBAAY,gBAAgB;IAC1B,gBAAgB,mBAAmB;IACnC,MAAM,SAAS;IACf,SAAS,YAAY;IACrB,MAAM,SAAS;CAChB;AAED,wBAAsB,OAAO,CAC3B,IAAI,EAAE,gBAAgB,GAAG,2BAA2B,EACpD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC3B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,CAAC,CAWtB"}
@@ -0,0 +1,27 @@
1
+ import { errors } from '@takaro/util';
2
+ import { SdtdConnectionInfo } from './gameservers/7d2d/connectionInfo.js';
3
+ import { SevenDaysToDie } from './gameservers/7d2d/index.js';
4
+ import { RustConnectionInfo } from './gameservers/rust/connectionInfo.js';
5
+ import { Rust } from './gameservers/rust/index.js';
6
+ import { GenericConnectionInfo } from './gameservers/generic/connectionInfo.js';
7
+ import { Generic } from './gameservers/generic/index.js';
8
+ export var GAME_SERVER_TYPE;
9
+ (function (GAME_SERVER_TYPE) {
10
+ GAME_SERVER_TYPE["SEVENDAYSTODIE"] = "SEVENDAYSTODIE";
11
+ GAME_SERVER_TYPE["RUST"] = "RUST";
12
+ GAME_SERVER_TYPE["GENERIC"] = "GENERIC";
13
+ GAME_SERVER_TYPE["MOCK"] = "MOCK";
14
+ })(GAME_SERVER_TYPE || (GAME_SERVER_TYPE = {}));
15
+ export async function getGame(type, connectionInfo, settings, gameServerId) {
16
+ switch (type) {
17
+ case GAME_SERVER_TYPE.SEVENDAYSTODIE:
18
+ return new SevenDaysToDie(new SdtdConnectionInfo(connectionInfo), settings);
19
+ case GAME_SERVER_TYPE.RUST:
20
+ return new Rust(new RustConnectionInfo(connectionInfo), settings);
21
+ case GAME_SERVER_TYPE.GENERIC:
22
+ return new Generic(new GenericConnectionInfo(connectionInfo), settings, gameServerId);
23
+ default:
24
+ throw new errors.NotImplementedError();
25
+ }
26
+ }
27
+ //# sourceMappingURL=getGame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getGame.js","sourceRoot":"","sources":["../src/getGame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAEnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAEzD,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,qDAAmC,CAAA;IACnC,iCAAe,CAAA;IACf,uCAAqB,CAAA;IACrB,iCAAe,CAAA;AACjB,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAoD,EACpD,cAAuC,EACvC,QAA2B,EAC3B,YAAoB;IAEpB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,gBAAgB,CAAC,cAAc;YAClC,OAAO,IAAI,cAAc,CAAC,IAAI,kBAAkB,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC9E,KAAK,gBAAgB,CAAC,IAAI;YACxB,OAAO,IAAI,IAAI,CAAC,IAAI,kBAAkB,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAC;QACpE,KAAK,gBAAgB,CAAC,OAAO;YAC3B,OAAO,IAAI,OAAO,CAAC,IAAI,qBAAqB,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QACxF;YACE,MAAM,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC"}
@@ -0,0 +1,99 @@
1
+ import { TakaroEmitter } from '../TakaroEmitter.js';
2
+ import { IGamePlayer, IPosition } from '@takaro/modules';
3
+ import { TakaroDTO } from '@takaro/util';
4
+ export declare class CommandOutput extends TakaroDTO<CommandOutput> {
5
+ rawResult: string;
6
+ success: boolean;
7
+ errorMessage?: string;
8
+ }
9
+ export declare class TestReachabilityOutputDTO extends TakaroDTO<TestReachabilityOutputDTO> {
10
+ connectable: boolean;
11
+ reason?: string;
12
+ latency?: number;
13
+ }
14
+ /**
15
+ * This is used whenever we want to target a specific player
16
+ * We only allow a subset of IGamePlayer here because to work across gameservers we need to be generic
17
+ * Eg, if we allow users to reference players by Steam ID, that wont work for all gameservers. Not all gameservers have Steam integration
18
+ */
19
+ export declare class IPlayerReferenceDTO extends TakaroDTO<IPlayerReferenceDTO> {
20
+ gameId: string;
21
+ }
22
+ export declare class IItemDTO extends TakaroDTO<IItemDTO> {
23
+ name: string;
24
+ code: string;
25
+ description: string;
26
+ amount?: number;
27
+ quality?: string;
28
+ }
29
+ export declare class IMessageOptsDTO extends TakaroDTO<IMessageOptsDTO> {
30
+ /** When specified, will send a DM to this player instead of a global message */
31
+ recipient?: IPlayerReferenceDTO;
32
+ /** When specified, overrides the server chat name from settings */
33
+ senderNameOverride?: string;
34
+ }
35
+ export declare class BanDTO extends TakaroDTO<BanDTO> {
36
+ player: IGamePlayer;
37
+ reason: string;
38
+ expiresAt: string | null;
39
+ }
40
+ export declare class MapInfoDTO extends TakaroDTO<MapInfoDTO> {
41
+ enabled: boolean;
42
+ mapBlockSize: number;
43
+ maxZoom: number;
44
+ mapSizeX: number;
45
+ mapSizeY: number;
46
+ mapSizeZ: number;
47
+ }
48
+ export declare enum EntityType {
49
+ HOSTILE = "hostile",
50
+ FRIENDLY = "friendly",
51
+ NEUTRAL = "neutral"
52
+ }
53
+ export declare class IEntityDTO extends TakaroDTO<IEntityDTO> {
54
+ code: string;
55
+ name: string;
56
+ description: string;
57
+ type: EntityType;
58
+ metadata?: Record<string, unknown>;
59
+ }
60
+ export declare class ILocationDTO extends TakaroDTO<ILocationDTO> {
61
+ position: IPosition;
62
+ radius?: number;
63
+ sizeX?: number;
64
+ sizeY?: number;
65
+ sizeZ?: number;
66
+ name: string;
67
+ code?: string;
68
+ metadata?: Record<string, unknown>;
69
+ }
70
+ export interface IGameServer {
71
+ connectionInfo: unknown;
72
+ getEventEmitter(): TakaroEmitter;
73
+ getPlayer(player: IPlayerReferenceDTO): Promise<IGamePlayer | null>;
74
+ getPlayers(): Promise<IGamePlayer[]>;
75
+ getPlayerLocation(player: IPlayerReferenceDTO): Promise<IPosition | null>;
76
+ getPlayerInventory(player: IPlayerReferenceDTO): Promise<IItemDTO[]>;
77
+ giveItem(player: IPlayerReferenceDTO, item: string, amount: number, quality?: string): Promise<void>;
78
+ listItems(): Promise<IItemDTO[]>;
79
+ listEntities(): Promise<IEntityDTO[]>;
80
+ listLocations(): Promise<ILocationDTO[]>;
81
+ executeConsoleCommand(rawCommand: string): Promise<CommandOutput>;
82
+ sendMessage(message: string, opts: IMessageOptsDTO): Promise<void>;
83
+ teleportPlayer(player: IPlayerReferenceDTO, x: number, y: number, z: number, dimension?: string): Promise<void>;
84
+ /**
85
+ * Try and connect to the gameserver
86
+ * If anything goes wrong, this function will report a detailed reason
87
+ */
88
+ testReachability(): Promise<TestReachabilityOutputDTO>;
89
+ kickPlayer(player: IPlayerReferenceDTO, reason: string): Promise<void>;
90
+ banPlayer(options: BanDTO): Promise<void>;
91
+ unbanPlayer(player: IPlayerReferenceDTO): Promise<void>;
92
+ listBans(): Promise<BanDTO[]>;
93
+ shutdown(): Promise<void>;
94
+ getMapInfo(): Promise<MapInfoDTO>;
95
+ getMapTile(x: number, y: number, z: number): Promise<string>;
96
+ }
97
+ export type GameServerActions = keyof Omit<IGameServer, 'getEventEmitter' | 'connectionInfo'>;
98
+ export declare const GAME_SERVER_ACTIONS: GameServerActions[];
99
+ //# sourceMappingURL=GameServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GameServer.d.ts","sourceRoot":"","sources":["../../src/interfaces/GameServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,235 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { IGamePlayer, IPosition } from '@takaro/modules';
11
+ import { TakaroDTO } from '@takaro/util';
12
+ import { IsBoolean, IsEnum, IsISO8601, IsNumber, IsObject, IsOptional, IsString, ValidateNested, } from 'class-validator';
13
+ import { Type } from 'class-transformer';
14
+ export class CommandOutput extends TakaroDTO {
15
+ }
16
+ __decorate([
17
+ IsString(),
18
+ __metadata("design:type", String)
19
+ ], CommandOutput.prototype, "rawResult", void 0);
20
+ __decorate([
21
+ IsBoolean(),
22
+ __metadata("design:type", Boolean)
23
+ ], CommandOutput.prototype, "success", void 0);
24
+ __decorate([
25
+ IsOptional(),
26
+ IsString(),
27
+ __metadata("design:type", String)
28
+ ], CommandOutput.prototype, "errorMessage", void 0);
29
+ export class TestReachabilityOutputDTO extends TakaroDTO {
30
+ }
31
+ __decorate([
32
+ IsBoolean(),
33
+ __metadata("design:type", Boolean)
34
+ ], TestReachabilityOutputDTO.prototype, "connectable", void 0);
35
+ __decorate([
36
+ IsString(),
37
+ IsOptional(),
38
+ __metadata("design:type", String)
39
+ ], TestReachabilityOutputDTO.prototype, "reason", void 0);
40
+ __decorate([
41
+ IsOptional(),
42
+ IsNumber(),
43
+ __metadata("design:type", Number)
44
+ ], TestReachabilityOutputDTO.prototype, "latency", void 0);
45
+ /**
46
+ * This is used whenever we want to target a specific player
47
+ * We only allow a subset of IGamePlayer here because to work across gameservers we need to be generic
48
+ * Eg, if we allow users to reference players by Steam ID, that wont work for all gameservers. Not all gameservers have Steam integration
49
+ */
50
+ export class IPlayerReferenceDTO extends TakaroDTO {
51
+ }
52
+ __decorate([
53
+ IsString(),
54
+ __metadata("design:type", String)
55
+ ], IPlayerReferenceDTO.prototype, "gameId", void 0);
56
+ export class IItemDTO extends TakaroDTO {
57
+ }
58
+ __decorate([
59
+ IsString(),
60
+ __metadata("design:type", String)
61
+ ], IItemDTO.prototype, "name", void 0);
62
+ __decorate([
63
+ IsString(),
64
+ __metadata("design:type", String)
65
+ ], IItemDTO.prototype, "code", void 0);
66
+ __decorate([
67
+ IsString(),
68
+ IsOptional(),
69
+ __metadata("design:type", String)
70
+ ], IItemDTO.prototype, "description", void 0);
71
+ __decorate([
72
+ IsNumber(),
73
+ IsOptional(),
74
+ __metadata("design:type", Number)
75
+ ], IItemDTO.prototype, "amount", void 0);
76
+ __decorate([
77
+ IsString(),
78
+ IsOptional(),
79
+ __metadata("design:type", String)
80
+ ], IItemDTO.prototype, "quality", void 0);
81
+ export class IMessageOptsDTO extends TakaroDTO {
82
+ }
83
+ __decorate([
84
+ Type(() => IPlayerReferenceDTO),
85
+ ValidateNested(),
86
+ IsOptional()
87
+ /** When specified, will send a DM to this player instead of a global message */
88
+ ,
89
+ __metadata("design:type", IPlayerReferenceDTO)
90
+ ], IMessageOptsDTO.prototype, "recipient", void 0);
91
+ __decorate([
92
+ IsString(),
93
+ IsOptional()
94
+ /** When specified, overrides the server chat name from settings */
95
+ ,
96
+ __metadata("design:type", String)
97
+ ], IMessageOptsDTO.prototype, "senderNameOverride", void 0);
98
+ export class BanDTO extends TakaroDTO {
99
+ }
100
+ __decorate([
101
+ Type(() => IGamePlayer),
102
+ ValidateNested(),
103
+ __metadata("design:type", IGamePlayer)
104
+ ], BanDTO.prototype, "player", void 0);
105
+ __decorate([
106
+ IsString(),
107
+ __metadata("design:type", String)
108
+ ], BanDTO.prototype, "reason", void 0);
109
+ __decorate([
110
+ IsISO8601(),
111
+ IsOptional(),
112
+ __metadata("design:type", Object)
113
+ ], BanDTO.prototype, "expiresAt", void 0);
114
+ export class MapInfoDTO extends TakaroDTO {
115
+ }
116
+ __decorate([
117
+ IsBoolean(),
118
+ __metadata("design:type", Boolean)
119
+ ], MapInfoDTO.prototype, "enabled", void 0);
120
+ __decorate([
121
+ IsNumber(),
122
+ __metadata("design:type", Number)
123
+ ], MapInfoDTO.prototype, "mapBlockSize", void 0);
124
+ __decorate([
125
+ IsNumber(),
126
+ __metadata("design:type", Number)
127
+ ], MapInfoDTO.prototype, "maxZoom", void 0);
128
+ __decorate([
129
+ IsNumber(),
130
+ __metadata("design:type", Number)
131
+ ], MapInfoDTO.prototype, "mapSizeX", void 0);
132
+ __decorate([
133
+ IsNumber(),
134
+ __metadata("design:type", Number)
135
+ ], MapInfoDTO.prototype, "mapSizeY", void 0);
136
+ __decorate([
137
+ IsNumber(),
138
+ __metadata("design:type", Number)
139
+ ], MapInfoDTO.prototype, "mapSizeZ", void 0);
140
+ export var EntityType;
141
+ (function (EntityType) {
142
+ EntityType["HOSTILE"] = "hostile";
143
+ EntityType["FRIENDLY"] = "friendly";
144
+ EntityType["NEUTRAL"] = "neutral";
145
+ })(EntityType || (EntityType = {}));
146
+ export class IEntityDTO extends TakaroDTO {
147
+ }
148
+ __decorate([
149
+ IsString(),
150
+ __metadata("design:type", String)
151
+ ], IEntityDTO.prototype, "code", void 0);
152
+ __decorate([
153
+ IsString(),
154
+ __metadata("design:type", String)
155
+ ], IEntityDTO.prototype, "name", void 0);
156
+ __decorate([
157
+ IsString(),
158
+ IsOptional(),
159
+ __metadata("design:type", String)
160
+ ], IEntityDTO.prototype, "description", void 0);
161
+ __decorate([
162
+ IsEnum(Object.values(EntityType)),
163
+ IsOptional(),
164
+ __metadata("design:type", String)
165
+ ], IEntityDTO.prototype, "type", void 0);
166
+ __decorate([
167
+ IsObject(),
168
+ IsOptional(),
169
+ __metadata("design:type", Object)
170
+ ], IEntityDTO.prototype, "metadata", void 0);
171
+ export class ILocationDTO extends TakaroDTO {
172
+ }
173
+ __decorate([
174
+ ValidateNested(),
175
+ Type(() => IPosition),
176
+ __metadata("design:type", IPosition)
177
+ ], ILocationDTO.prototype, "position", void 0);
178
+ __decorate([
179
+ IsNumber(),
180
+ IsOptional(),
181
+ __metadata("design:type", Number)
182
+ ], ILocationDTO.prototype, "radius", void 0);
183
+ __decorate([
184
+ IsNumber(),
185
+ IsOptional(),
186
+ __metadata("design:type", Number)
187
+ ], ILocationDTO.prototype, "sizeX", void 0);
188
+ __decorate([
189
+ IsNumber(),
190
+ IsOptional(),
191
+ __metadata("design:type", Number)
192
+ ], ILocationDTO.prototype, "sizeY", void 0);
193
+ __decorate([
194
+ IsNumber(),
195
+ IsOptional(),
196
+ __metadata("design:type", Number)
197
+ ], ILocationDTO.prototype, "sizeZ", void 0);
198
+ __decorate([
199
+ IsString(),
200
+ __metadata("design:type", String)
201
+ ], ILocationDTO.prototype, "name", void 0);
202
+ __decorate([
203
+ IsString(),
204
+ IsOptional(),
205
+ __metadata("design:type", String)
206
+ ], ILocationDTO.prototype, "code", void 0);
207
+ __decorate([
208
+ IsObject(),
209
+ IsOptional(),
210
+ __metadata("design:type", Object)
211
+ ], ILocationDTO.prototype, "metadata", void 0);
212
+ // Also create a runtime array with all the actions
213
+ // This is used for class-validator
214
+ export const GAME_SERVER_ACTIONS = [
215
+ 'getPlayer',
216
+ 'getPlayers',
217
+ 'getPlayerLocation',
218
+ 'getPlayerInventory',
219
+ 'giveItem',
220
+ 'listItems',
221
+ 'listEntities',
222
+ 'listLocations',
223
+ 'executeConsoleCommand',
224
+ 'sendMessage',
225
+ 'teleportPlayer',
226
+ 'testReachability',
227
+ 'kickPlayer',
228
+ 'banPlayer',
229
+ 'unbanPlayer',
230
+ 'listBans',
231
+ 'shutdown',
232
+ 'getMapInfo',
233
+ 'getMapTile',
234
+ ];
235
+ //# sourceMappingURL=GameServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GameServer.js","sourceRoot":"","sources":["../../src/interfaces/GameServer.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export * from './interfaces/GameServer.js';
2
+ export { TakaroEmitter } from './TakaroEmitter.js';
3
+ export { SevenDaysToDie } from './gameservers/7d2d/index.js';
4
+ export { SdtdConnectionInfo, sdtdJsonSchema } from './gameservers/7d2d/connectionInfo.js';
5
+ export { Rust } from './gameservers/rust/index.js';
6
+ export { RustConnectionInfo, rustJsonSchema } from './gameservers/rust/connectionInfo.js';
7
+ export { getGame, GAME_SERVER_TYPE } from './getGame.js';
8
+ export { Generic } from './gameservers/generic/index.js';
9
+ export { TakaroConnector } from './gameservers/generic/connectorClient.js';
10
+ export { GenericEmitter } from './gameservers/generic/emitter.js';
11
+ export { GenericConnectionInfo, genericJsonSchema } from './gameservers/generic/connectionInfo.js';
12
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAE1F,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAE1F,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC"}
package/dist/main.js ADDED
@@ -0,0 +1,12 @@
1
+ export * from './interfaces/GameServer.js';
2
+ export { TakaroEmitter } from './TakaroEmitter.js';
3
+ export { SevenDaysToDie } from './gameservers/7d2d/index.js';
4
+ export { SdtdConnectionInfo, sdtdJsonSchema } from './gameservers/7d2d/connectionInfo.js';
5
+ export { Rust } from './gameservers/rust/index.js';
6
+ export { RustConnectionInfo, rustJsonSchema } from './gameservers/rust/connectionInfo.js';
7
+ export { getGame, GAME_SERVER_TYPE } from './getGame.js';
8
+ export { Generic } from './gameservers/generic/index.js';
9
+ export { TakaroConnector } from './gameservers/generic/connectorClient.js';
10
+ export { GenericEmitter } from './gameservers/generic/emitter.js';
11
+ export { GenericConnectionInfo, genericJsonSchema } from './gameservers/generic/connectionInfo.js';
12
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAE1F,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAE1F,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@takaro/gameserver",
3
+ "version": "0.0.0-next.0da151e",
4
+ "description": "Handles abstraction between Takaro and game servers",
5
+ "main": "dist/main.js",
6
+ "types": "dist/main.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "start:dev": "tsc --watch --preserveWatchOutput -p ./tsconfig.build.json",
10
+ "build": "tsc -p ./tsconfig.build.json",
11
+ "postbuild": "cp src/gameservers/7d2d/items-7d2d.json dist/gameservers/7d2d/items-7d2d.json"
12
+ },
13
+ "keywords": [],
14
+ "author": "",
15
+ "license": "ISC"
16
+ }
@@ -0,0 +1,146 @@
1
+ import 'reflect-metadata';
2
+
3
+ import {
4
+ BaseEvent,
5
+ EventChatMessage,
6
+ EventEntityKilled,
7
+ EventLogLine,
8
+ EventPlayerConnected,
9
+ EventPlayerDeath,
10
+ EventPlayerDisconnected,
11
+ GameEvents,
12
+ } from '@takaro/modules';
13
+ import { errors, isTakaroDTO, logger } from '@takaro/util';
14
+ import EventEmitter from 'events';
15
+ import { isPromise } from 'util/types';
16
+
17
+ const log = logger('TakaroEmitter');
18
+
19
+ /**
20
+ * Maps event types to their listener function signatures
21
+ * This allows our EventEmitter to be strongly typed
22
+ */
23
+ export interface IEventMap {
24
+ [GameEvents.LOG_LINE]: (log: EventLogLine) => Promise<void>;
25
+ [GameEvents.PLAYER_CONNECTED]: (player: EventPlayerConnected) => Promise<void>;
26
+ [GameEvents.PLAYER_DISCONNECTED]: (player: EventPlayerDisconnected) => Promise<void>;
27
+ [GameEvents.CHAT_MESSAGE]: (chatMessage: EventChatMessage) => Promise<void>;
28
+ [GameEvents.PLAYER_DEATH]: (playerDeath: EventPlayerDeath) => Promise<void>;
29
+ [GameEvents.ENTITY_KILLED]: (entityKilled: EventEntityKilled) => Promise<void>;
30
+ error: (error: errors.TakaroError | Error) => Promise<void> | void;
31
+ }
32
+
33
+ export abstract class TakaroEmitter {
34
+ private listenerMap: Map<keyof IEventMap, IEventMap[keyof IEventMap][]> = new Map();
35
+
36
+ abstract start(nodeEventEmitter?: EventEmitter): Promise<void>;
37
+ abstract stop(): Promise<void>;
38
+
39
+ constructor() {
40
+ return getErrorProxyHandler(this);
41
+ }
42
+
43
+ async emit<E extends keyof IEventMap>(event: E, data: BaseEvent<unknown> | Error) {
44
+ try {
45
+ // No listeners are attached, return early
46
+ if (!this.listenerMap.has(event)) return;
47
+
48
+ // Validate the data, it is user-input after all :)
49
+ if (isTakaroDTO(data)) {
50
+ if (!data.timestamp) data.timestamp = new Date().toISOString();
51
+ // await data.validate();
52
+ }
53
+
54
+ const listeners = this.listenerMap.get(event);
55
+
56
+ if (listeners) {
57
+ for (const listener of listeners) {
58
+ // We know this is okay because our listener map always corresponds to the right event
59
+ // This is implicit in our implementation and checked in the tests
60
+ // @ts-expect-error Can't get the types quite right :(
61
+ await listener(data);
62
+ }
63
+ }
64
+ } catch (error) {
65
+ this.emit('error', error as Error);
66
+ }
67
+ }
68
+
69
+ on<E extends keyof IEventMap>(event: E, listener: IEventMap[E]): this {
70
+ const existing = this.listenerMap.get(event) || [];
71
+ this.listenerMap.set(event, [...existing, listener]);
72
+ return this;
73
+ }
74
+
75
+ off<E extends keyof IEventMap>(event: E, listener: IEventMap[E]): this {
76
+ const listeners = this.listenerMap.get(event);
77
+
78
+ if (listeners) {
79
+ this.listenerMap.set(
80
+ event,
81
+ listeners.filter((l) => l !== listener),
82
+ );
83
+ }
84
+
85
+ return this;
86
+ }
87
+
88
+ removeAllListeners(): this {
89
+ this.listenerMap.clear();
90
+ return this;
91
+ }
92
+
93
+ hasErrorListener() {
94
+ return this.listenerMap.has('error');
95
+ }
96
+ }
97
+
98
+ export function getErrorProxyHandler<T extends TakaroEmitter>(emitter: T) {
99
+ const errorProxyHandler: ProxyHandler<T> = {
100
+ construct(target: any, argArray) {
101
+ return Reflect.construct(target, argArray, TakaroEmitter);
102
+ },
103
+
104
+ set: function (obj, prop: keyof TakaroEmitter, value) {
105
+ obj[prop] = value;
106
+ return true;
107
+ },
108
+
109
+ get(target, prop: keyof TakaroEmitter) {
110
+ return async (...[one, two]: any[]) => {
111
+ try {
112
+ // Check if callable function
113
+ if (typeof target[prop] === 'function') {
114
+ return await target[prop](one, two);
115
+ // Or if its a Promise, await it
116
+ } else if (isPromise(target[prop])) {
117
+ return target[prop];
118
+ }
119
+ // Otherwise, return the value
120
+ return target[prop];
121
+ } catch (error) {
122
+ if (!target.hasErrorListener()) {
123
+ log.error('Unhandled error', error);
124
+ const err = new Error(
125
+ 'Unhandled error in TakaroEmitter, attach a listener to the "error" event to handle this',
126
+ );
127
+ Error.captureStackTrace(err);
128
+ throw err;
129
+ }
130
+
131
+ if (error instanceof errors.TakaroError) {
132
+ await target.emit('error', error);
133
+ } else if (error instanceof Error) {
134
+ await target.emit('error', error);
135
+ }
136
+
137
+ if (!Object.prototype.hasOwnProperty.call(TakaroEmitter.prototype, prop)) {
138
+ return Promise.reject(error);
139
+ }
140
+ }
141
+ };
142
+ },
143
+ };
144
+
145
+ return new Proxy(emitter, errorProxyHandler);
146
+ }