omegga 1.2.8 → 1.3.0

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 (255) hide show
  1. package/README.md +20 -1
  2. package/dist/brickadia/config.js +26 -90
  3. package/dist/brickadia/config.js.map +1 -1
  4. package/dist/brickadia/server.js +294 -293
  5. package/dist/brickadia/server.js.map +1 -1
  6. package/dist/cli/auth.js +149 -177
  7. package/dist/cli/auth.js.map +1 -1
  8. package/dist/cli/config.js +64 -66
  9. package/dist/cli/config.js.map +1 -1
  10. package/dist/cli/index.js +14 -14
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/installer.js +37 -43
  13. package/dist/cli/installer.js.map +1 -1
  14. package/dist/cli/plugin.js +651 -682
  15. package/dist/cli/plugin.js.map +1 -1
  16. package/dist/cli/terminal.js +811 -733
  17. package/dist/cli/terminal.js.map +1 -1
  18. package/dist/config/formats/format_js.js +6 -6
  19. package/dist/config/formats/format_js.js.map +1 -1
  20. package/dist/config/formats/format_yml.js +7 -10
  21. package/dist/config/formats/format_yml.js.map +1 -1
  22. package/dist/config/index.js +46 -68
  23. package/dist/config/index.js.map +1 -1
  24. package/dist/config/reader.js +16 -27
  25. package/dist/config/reader.js.map +1 -1
  26. package/dist/config/validator.js +23 -25
  27. package/dist/config/validator.js.map +1 -1
  28. package/dist/config/writer.js +11 -21
  29. package/dist/config/writer.js.map +1 -1
  30. package/dist/index.js +18 -64
  31. package/dist/index.js.map +1 -1
  32. package/dist/info/default_commands.json.js +39 -0
  33. package/dist/info/default_commands.json.js.map +1 -0
  34. package/dist/logger.js +61 -60
  35. package/dist/logger.js.map +1 -1
  36. package/dist/main.js +424 -471
  37. package/dist/main.js.map +1 -1
  38. package/dist/omegga/auth.js +101 -148
  39. package/dist/omegga/auth.js.map +1 -1
  40. package/dist/omegga/commandInjector.js +261 -251
  41. package/dist/omegga/commandInjector.js.map +1 -1
  42. package/dist/omegga/index.js +14 -52
  43. package/dist/omegga/index.js.map +1 -1
  44. package/dist/omegga/logWrangler.js +224 -275
  45. package/dist/omegga/logWrangler.js.map +1 -1
  46. package/dist/omegga/matchers/auth.js +36 -50
  47. package/dist/omegga/matchers/auth.js.map +1 -1
  48. package/dist/omegga/matchers/chat.js +49 -71
  49. package/dist/omegga/matchers/chat.js.map +1 -1
  50. package/dist/omegga/matchers/command.js +25 -36
  51. package/dist/omegga/matchers/command.js.map +1 -1
  52. package/dist/omegga/matchers/exit.js +15 -18
  53. package/dist/omegga/matchers/exit.js.map +1 -1
  54. package/dist/omegga/matchers/index.js +26 -40
  55. package/dist/omegga/matchers/index.js.map +1 -1
  56. package/dist/omegga/matchers/init.js +20 -23
  57. package/dist/omegga/matchers/init.js.map +1 -1
  58. package/dist/omegga/matchers/interact.js +58 -64
  59. package/dist/omegga/matchers/interact.js.map +1 -1
  60. package/dist/omegga/matchers/join.js +74 -95
  61. package/dist/omegga/matchers/join.js.map +1 -1
  62. package/dist/omegga/matchers/leave.js +43 -56
  63. package/dist/omegga/matchers/leave.js.map +1 -1
  64. package/dist/omegga/matchers/mapChange.js +26 -35
  65. package/dist/omegga/matchers/mapChange.js.map +1 -1
  66. package/dist/omegga/matchers/minigameJoin.js +24 -31
  67. package/dist/omegga/matchers/minigameJoin.js.map +1 -1
  68. package/dist/omegga/matchers/version.js +42 -49
  69. package/dist/omegga/matchers/version.js.map +1 -1
  70. package/dist/omegga/player.js +527 -527
  71. package/dist/omegga/player.js.map +1 -1
  72. package/dist/omegga/plugin/interface.js +91 -98
  73. package/dist/omegga/plugin/interface.js.map +1 -1
  74. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js +524 -429
  75. package/dist/omegga/plugin/plugin_jsonrpc_stdio.js.map +1 -1
  76. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js +282 -294
  77. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.js.map +1 -1
  78. package/dist/omegga/plugin/plugin_node_safe.js +365 -393
  79. package/dist/omegga/plugin/plugin_node_safe.js.map +1 -1
  80. package/dist/omegga/plugin/plugin_node_unsafe.js +119 -179
  81. package/dist/omegga/plugin/plugin_node_unsafe.js.map +1 -1
  82. package/dist/omegga/plugin.js +402 -347
  83. package/dist/omegga/plugin.js.map +1 -1
  84. package/dist/omegga/server.js +742 -774
  85. package/dist/omegga/server.js.map +1 -1
  86. package/dist/omegga/wrapper.js +64 -91
  87. package/dist/omegga/wrapper.js.map +1 -1
  88. package/dist/plugin.js +11 -31
  89. package/dist/plugin.js.map +1 -1
  90. package/dist/softconfig.js +121 -100
  91. package/dist/softconfig.js.map +1 -1
  92. package/dist/updater/steam.js +97 -112
  93. package/dist/updater/steam.js.map +1 -1
  94. package/dist/util/brdb.js +496 -528
  95. package/dist/util/brdb.js.map +1 -1
  96. package/dist/util/brick/checkBounds.js +11 -15
  97. package/dist/util/brick/checkBounds.js.map +1 -1
  98. package/dist/util/brick/constants.js +723 -174
  99. package/dist/util/brick/constants.js.map +1 -1
  100. package/dist/util/brick/displayName.js +204 -211
  101. package/dist/util/brick/displayName.js.map +1 -1
  102. package/dist/util/brick/getBounds.js +29 -41
  103. package/dist/util/brick/getBounds.js.map +1 -1
  104. package/dist/util/brick/getBrickSize.js +6 -7
  105. package/dist/util/brick/getBrickSize.js.map +1 -1
  106. package/dist/util/brick/getScaleAxis.js +24 -30
  107. package/dist/util/brick/getScaleAxis.js.map +1 -1
  108. package/dist/util/brick/index.js +8 -29
  109. package/dist/util/brick/index.js.map +1 -1
  110. package/dist/util/brick/rotate.js +29 -34
  111. package/dist/util/brick/rotate.js.map +1 -1
  112. package/dist/util/brick/setOwnership.js +13 -19
  113. package/dist/util/brick/setOwnership.js.map +1 -1
  114. package/dist/util/chat.js +53 -44
  115. package/dist/util/chat.js.map +1 -1
  116. package/dist/util/color.js +112 -124
  117. package/dist/util/color.js.map +1 -1
  118. package/dist/util/file.js +54 -98
  119. package/dist/util/file.js.map +1 -1
  120. package/dist/util/index.js +84 -106
  121. package/dist/util/index.js.map +1 -1
  122. package/dist/util/map.js +18 -20
  123. package/dist/util/map.js.map +1 -1
  124. package/dist/util/pattern.js +6 -9
  125. package/dist/util/pattern.js.map +1 -1
  126. package/dist/util/time.js +31 -34
  127. package/dist/util/time.js.map +1 -1
  128. package/dist/util/uuid.js +10 -8
  129. package/dist/util/uuid.js.map +1 -1
  130. package/dist/util/wsl.js +19 -25
  131. package/dist/util/wsl.js.map +1 -1
  132. package/dist/version.js +7 -9
  133. package/dist/version.js.map +1 -1
  134. package/dist/webserver/backend/api.js +784 -874
  135. package/dist/webserver/backend/api.js.map +1 -1
  136. package/dist/webserver/backend/calendar.js +14 -17
  137. package/dist/webserver/backend/calendar.js.map +1 -1
  138. package/dist/webserver/backend/database.js +563 -613
  139. package/dist/webserver/backend/database.js.map +1 -1
  140. package/dist/webserver/backend/index.js +153 -191
  141. package/dist/webserver/backend/index.js.map +1 -1
  142. package/dist/webserver/backend/metrics.js +219 -248
  143. package/dist/webserver/backend/metrics.js.map +1 -1
  144. package/dist/webserver/backend/util.js +47 -68
  145. package/dist/webserver/backend/util.js.map +1 -1
  146. package/dist/worker.js +322 -0
  147. package/dist/worker.js.map +1 -0
  148. package/package.json +14 -10
  149. package/templates/safe-ts/omegga.d.ts +2 -2
  150. package/vite.backend.config.mts +46 -0
  151. package/vite.frontend.config.mts +58 -0
  152. package/vitest.backend.config.mts +7 -0
  153. package/dist/brickadia/config.d.ts +0 -3
  154. package/dist/brickadia/presets.d.ts +0 -65
  155. package/dist/brickadia/presets.js +0 -3
  156. package/dist/brickadia/presets.js.map +0 -1
  157. package/dist/brickadia/server.d.ts +0 -36
  158. package/dist/brickadia/types.d.ts +0 -45
  159. package/dist/brickadia/types.js +0 -3
  160. package/dist/brickadia/types.js.map +0 -1
  161. package/dist/cli/auth.d.ts +0 -26
  162. package/dist/cli/config.d.ts +0 -10
  163. package/dist/cli/index.d.ts +0 -30
  164. package/dist/cli/installer.d.ts +0 -1
  165. package/dist/cli/plugin.d.ts +0 -22
  166. package/dist/cli/terminal.d.ts +0 -25
  167. package/dist/config/authorizer.d.ts +0 -2
  168. package/dist/config/authorizer.js +0 -38
  169. package/dist/config/authorizer.js.map +0 -1
  170. package/dist/config/formats/format_js.d.ts +0 -3
  171. package/dist/config/formats/format_yml.d.ts +0 -3
  172. package/dist/config/index.d.ts +0 -18
  173. package/dist/config/reader.d.ts +0 -3
  174. package/dist/config/types.d.ts +0 -50
  175. package/dist/config/types.js +0 -3
  176. package/dist/config/types.js.map +0 -1
  177. package/dist/config/validator.d.ts +0 -6
  178. package/dist/config/writer.d.ts +0 -3
  179. package/dist/index.d.ts +0 -22
  180. package/dist/info/default_commands.json +0 -29
  181. package/dist/logger.d.ts +0 -41
  182. package/dist/main.d.ts +0 -1
  183. package/dist/omegga/auth.d.ts +0 -9
  184. package/dist/omegga/commandInjector.d.ts +0 -35
  185. package/dist/omegga/index.d.ts +0 -7
  186. package/dist/omegga/logWrangler.d.ts +0 -32
  187. package/dist/omegga/matchers/auth.d.ts +0 -10
  188. package/dist/omegga/matchers/chat.d.ts +0 -10
  189. package/dist/omegga/matchers/command.d.ts +0 -7
  190. package/dist/omegga/matchers/exit.d.ts +0 -3
  191. package/dist/omegga/matchers/index.d.ts +0 -3
  192. package/dist/omegga/matchers/init.d.ts +0 -3
  193. package/dist/omegga/matchers/interact.d.ts +0 -4
  194. package/dist/omegga/matchers/join.d.ts +0 -4
  195. package/dist/omegga/matchers/leave.d.ts +0 -4
  196. package/dist/omegga/matchers/mapChange.d.ts +0 -3
  197. package/dist/omegga/matchers/minigameJoin.d.ts +0 -9
  198. package/dist/omegga/matchers/types.d.ts +0 -5
  199. package/dist/omegga/matchers/types.js +0 -3
  200. package/dist/omegga/matchers/types.js.map +0 -1
  201. package/dist/omegga/matchers/version.d.ts +0 -3
  202. package/dist/omegga/player.d.ts +0 -81
  203. package/dist/omegga/plugin/interface.d.ts +0 -30
  204. package/dist/omegga/plugin/plugin_jsonrpc_stdio.d.ts +0 -23
  205. package/dist/omegga/plugin/plugin_node_safe/proxyOmegga.d.ts +0 -145
  206. package/dist/omegga/plugin/plugin_node_safe/worker.d.ts +0 -1
  207. package/dist/omegga/plugin/plugin_node_safe/worker.js +0 -367
  208. package/dist/omegga/plugin/plugin_node_safe/worker.js.map +0 -1
  209. package/dist/omegga/plugin/plugin_node_safe.d.ts +0 -23
  210. package/dist/omegga/plugin/plugin_node_unsafe.d.ts +0 -13
  211. package/dist/omegga/plugin.d.ts +0 -63
  212. package/dist/omegga/server.d.ts +0 -166
  213. package/dist/omegga/types.d.ts +0 -49
  214. package/dist/omegga/types.js +0 -3
  215. package/dist/omegga/types.js.map +0 -1
  216. package/dist/omegga/wrapper.d.ts +0 -32
  217. package/dist/plugin.d.ts +0 -916
  218. package/dist/softconfig.d.ts +0 -67
  219. package/dist/tsconfig.tsbuildinfo +0 -1
  220. package/dist/updater/index.d.ts +0 -1
  221. package/dist/updater/index.js +0 -10
  222. package/dist/updater/index.js.map +0 -1
  223. package/dist/updater/steam.d.ts +0 -52
  224. package/dist/util/brdb.d.ts +0 -31
  225. package/dist/util/brick/checkBounds.d.ts +0 -8
  226. package/dist/util/brick/constants.d.ts +0 -18
  227. package/dist/util/brick/displayName.d.ts +0 -7
  228. package/dist/util/brick/getBounds.d.ts +0 -5
  229. package/dist/util/brick/getBrickSize.d.ts +0 -3
  230. package/dist/util/brick/getScaleAxis.d.ts +0 -3
  231. package/dist/util/brick/index.d.ts +0 -14
  232. package/dist/util/brick/rotate.d.ts +0 -16
  233. package/dist/util/brick/setOwnership.d.ts +0 -12
  234. package/dist/util/chat.d.ts +0 -23
  235. package/dist/util/color.d.ts +0 -13
  236. package/dist/util/file.d.ts +0 -5
  237. package/dist/util/index.d.ts +0 -183
  238. package/dist/util/map.d.ts +0 -6
  239. package/dist/util/pattern.d.ts +0 -1
  240. package/dist/util/time.d.ts +0 -39
  241. package/dist/util/uuid.d.ts +0 -3
  242. package/dist/util/wsl.d.ts +0 -2
  243. package/dist/version.d.ts +0 -2
  244. package/dist/webserver/backend/api.d.ts +0 -115
  245. package/dist/webserver/backend/calendar.d.ts +0 -5
  246. package/dist/webserver/backend/database.d.ts +0 -150
  247. package/dist/webserver/backend/index.d.ts +0 -30
  248. package/dist/webserver/backend/metrics.d.ts +0 -3
  249. package/dist/webserver/backend/types.d.ts +0 -114
  250. package/dist/webserver/backend/types.js +0 -3
  251. package/dist/webserver/backend/types.js.map +0 -1
  252. package/dist/webserver/backend/util.d.ts +0 -2
  253. package/dist/webserver/index.d.ts +0 -2
  254. package/dist/webserver/index.js +0 -9
  255. package/dist/webserver/index.js.map +0 -1
@@ -1,260 +1,270 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const lodash_1 = __importDefault(require("lodash"));
7
- const _util_1 = require("../util");
8
- const logger_1 = __importDefault(require("../logger"));
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const _ = require("lodash");
4
+ const index = require("../util/index.js");
5
+ const logger = require("../logger.js");
9
6
  const buildTableHeaderRegex = (header) => {
10
- const columns = header.match(/[^|]+/g);
11
- return new RegExp(columns // get all strings between the |'s'
12
- .map((line, i) => [
13
- line.slice(1, -1),
14
- line.length - (i === columns.length - 1 ? 1 : 2),
15
- ]) // calculate the lengths (and remove the spaces)
16
- .map(([name, len]) => ` (?<${name.trim().toLowerCase()}>.{${len}})( |$)`) // create a regex pattern to match strings of that length (and trim off whitespace at the end)
17
- .join('\\|')); // join the regexes with the |
7
+ const columns = header.match(/[^|]+/g);
8
+ return new RegExp(
9
+ columns.map((line, i) => [
10
+ line.slice(1, -1),
11
+ line.length - (i === columns.length - 1 ? 1 : 2)
12
+ ]).map(
13
+ ([name, len]) => ` (?<${name.trim().toLowerCase()}>.{${len}})( |$)`
14
+ ).join("\\|")
15
+ );
18
16
  };
19
- // A list of commands that can be injected to things with the log wrangler
20
- /**
21
- * List of injected commands
22
- */
23
17
  const COMMANDS = {
24
- /**
25
- * Get a server status object containing bricks, time, players, player ping, player roles, etc
26
- */
27
- async getServerStatus() {
28
- const statusLines = await this.watchLogChunk('Server.Status', /^LogConsoleCommands: (.+)$/, {
29
- first: match => match[1].startsWith('Server Name:'),
30
- timeoutDelay: 1000,
31
- });
32
- // the table lines all start with '* '
33
- // find all those lines, and remove the asterisk
34
- const [tableHeader, ...tableLines] = statusLines
35
- .filter(l => l[1].startsWith('* '))
36
- .map(l => l[1].slice(1));
37
- // use the size of each column to build a regex that matches each row
38
- const columnRegExp = buildTableHeaderRegex(tableHeader);
39
- const status = {
40
- // easily extract certain values from the server status
41
- serverName: statusLines[0][1].match(/^Server Name: (.*)$/)[1],
42
- description: statusLines[1][1].match(/^Description: (.*)$/)[1],
43
- bricks: Number(statusLines[2][1].match(/^Bricks: (\d+)$/)[1]),
44
- components: Number(statusLines[3][1].match(/^Components: (\d+)$/)[1]),
45
- time: _util_1.time.parseDuration(statusLines[4][1].match(/^Time: (.*)$/)[1]),
46
- // extract players using the generated table regex
47
- players: tableLines.map(l => {
48
- // match the player row with the generated regex
49
- const { groups: { name, ping, time: online, roles, address, id }, } = l.match(columnRegExp);
50
- // trim and parse the matched data
51
- return {
52
- name: name.trim(),
53
- ping: _util_1.time.parseDuration(ping.trim()),
54
- time: _util_1.time.parseDuration(online.trim()),
55
- roles: roles
56
- .trim()
57
- .split(', ')
58
- .filter(r => r.length > 0), // roles are split by ', '
59
- address: address.replace('(Owner)', '').trim(),
60
- id: id.trim(),
61
- };
62
- }),
18
+ /**
19
+ * Get a server status object containing bricks, time, players, player ping, player roles, etc
20
+ */
21
+ async getServerStatus() {
22
+ const statusLines = await this.watchLogChunk(
23
+ "Server.Status",
24
+ /^LogConsoleCommands: (.+)$/,
25
+ {
26
+ first: (match) => match[1].startsWith("Server Name:"),
27
+ timeoutDelay: 1e3
28
+ }
29
+ );
30
+ const [tableHeader, ...tableLines] = statusLines.filter((l) => l[1].startsWith("* ")).map((l) => l[1].slice(1));
31
+ const columnRegExp = buildTableHeaderRegex(tableHeader);
32
+ const status = {
33
+ // easily extract certain values from the server status
34
+ serverName: statusLines[0][1].match(/^Server Name: (.*)$/)[1],
35
+ description: statusLines[1][1].match(/^Description: (.*)$/)[1],
36
+ bricks: Number(statusLines[2][1].match(/^Bricks: (\d+)$/)[1]),
37
+ components: Number(statusLines[3][1].match(/^Components: (\d+)$/)[1]),
38
+ time: index.time.parseDuration(statusLines[4][1].match(/^Time: (.*)$/)[1]),
39
+ // extract players using the generated table regex
40
+ players: tableLines.map((l) => {
41
+ const {
42
+ groups: { name, ping, time: online, roles, address, id }
43
+ } = l.match(columnRegExp);
44
+ return {
45
+ name: name.trim(),
46
+ ping: index.time.parseDuration(ping.trim()),
47
+ time: index.time.parseDuration(online.trim()),
48
+ roles: roles.trim().split(", ").filter((r) => r.length > 0),
49
+ // roles are split by ', '
50
+ address: address.replace("(Owner)", "").trim(),
51
+ id: id.trim()
63
52
  };
64
- return status;
65
- },
66
- /**
67
- * Get a list of minigames
68
- * @return Minigame List
69
- */
70
- async listMinigames() {
71
- const minigameLines = await this.watchLogChunk('Server.Minigames.List', /^LogConsoleCommands: (.+)$/, {
72
- first: match => match[1].startsWith('Minigame Count:'),
73
- timeoutDelay: 1000,
74
- });
75
- // the table lines all start with '* '
76
- // find all those lines, and remove the asterisk
77
- const [tableHeader, ...tableLines] = minigameLines
78
- .filter(l => l[1].startsWith('* '))
79
- .map(l => l[1].slice(1));
80
- // use the size of each column to build a regex that matches each row
81
- const columnRegExp = buildTableHeaderRegex(tableHeader);
82
- return tableLines.map(l => {
83
- // match the player row with the generated regex
84
- const { groups: { id, name, ownername, ownerid, member }, } = l.match(columnRegExp);
85
- // trim and parse the matched data
86
- return {
87
- index: Number(id),
88
- name: name.trim(),
89
- numMembers: Number(member),
90
- owner: { name: ownername.trim(), id: ownerid },
91
- };
92
- });
93
- },
94
- // async getAllPawnData<T extends PawnDataField<string, any>[]>(
95
- // fields: T
96
- // ): Promise<{
97
- // controller: string;
98
- // data: FromEntriesDataField<[PawnDataField<'pawn', string>, ...T]>;
99
- // }> {
100
- // const restFields: [PawnDataField<'pawn', string>, ...T] = [
101
- // {
102
- // command: 'GetAll BP_PlayerController_C Pawn',
103
- // object: 'BP_PlayerController_C',
104
- // objectMatcher: /(?<controller>BP_PlayerController_C_\d+)/,
105
- // objectField: 'Pawn',
106
- // valueMatcher:
107
- // /(?:None|BP_FigureV2_C'.+?:PersistentLevel.(?<pawn>BP_FigureV2_C_\d+)')?$/,
108
- // valueTransform: matches => matches.groups.pawn ?? null,
109
- // field: 'pawn',
110
- // } as PawnDataField<'pawn', string>,
111
- // ...fields,
112
- // ];
113
- // return {
114
- // controller: 'test',
115
- // data: Object.fromEntries(
116
- // restFields.map(f => [
117
- // f.field,
118
- // f.valueTransform({ groups: { pawn: 'foo' } } as any),
119
- // ])
120
- // ) as FromEntriesDataField<[PawnDataField<'pawn', string>, ...T]>,
121
- // };
122
- // },
123
- /**
124
- * get every player's position and alive states
125
- */
126
- async getAllPlayerPositions() {
127
- const pawnRegExp = /(?<index>\d+)\) BP_PlayerController_C .+?PersistentLevel\.(?<controller>BP_PlayerController_C_\d+)\.Pawn = .*?(?:None|BP_FigureV2_C'.+?:PersistentLevel.(?<pawn>BP_FigureV2_C_\d+)')?$/;
128
- const posRegExp = /(?<index>\d+)\) CapsuleComponent .+?PersistentLevel\.(?<pawn>BP_FigureV2_C_\d+)\.CollisionCylinder\.RelativeLocation = \(X=(?<x>[\d.-]+),Y=(?<y>[\d.-]+),Z=(?<z>[\d.-]+)\)$/;
129
- const deadFigureRegExp = /(?<index>\d+)\) BP_FigureV2_C .+?PersistentLevel\.(?<pawn>BP_FigureV2_C_\d+)\.bIsDead = (?<dead>(True|False))$/;
130
- // wait for the pawn and position watchers to return all the results
131
- const [pawns, deadFigures, positions] = await Promise.all([
132
- this.watchLogChunk('GetAll BP_PlayerController_C Pawn', pawnRegExp, {
133
- first: 'index',
134
- timeoutDelay: 250,
135
- }),
136
- this.watchLogChunk('GetAll BP_FigureV2_C bIsDead', deadFigureRegExp, {
137
- first: 'index',
138
- timeoutDelay: 250,
139
- }),
140
- this.watchLogChunk('GetAll SceneComponent RelativeLocation Name=CollisionCylinder', posRegExp, { first: 'index', timeoutDelay: 250 }),
141
- ]);
142
- return (pawns
143
- // iterate through the pawn+controllers
144
- .map(pawn => ({
145
- // find the player for the associated controller
146
- player: this.getPlayer(pawn.groups.controller),
147
- // find the position for the associated pawn
148
- pos: positions.find(pos => pawn.groups.pawn === pos.groups.pawn),
149
- isDead: deadFigures.find(dead => pawn.groups.pawn === dead.groups.pawn),
150
- pawn,
151
- }))
152
- // filter by only those who have both player. previously we filtered by position but this breaks for players without a pawn, instead it's preferable to pass null
153
- .filter(p => p.player)
154
- // turn the position into a [x, y, z] number array (last 3 items in the array)
155
- .map(p => ({
156
- player: p.player,
157
- pawn: p.pawn.groups.pawn || null,
158
- pos: p.pos ? p.pos.slice(3).map(Number) : null,
159
- isDead: p.isDead ? p.isDead.groups.dead === 'True' : true,
160
- })));
161
- },
162
- /**
163
- * get all minigames and their players (and the player's teams)
164
- */
165
- async getMinigames() {
166
- // patterns to match the console logs
167
- const ruleNameRegExp = /^(?<index>\d+)\) BP_Ruleset_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.RulesetName = (?<name>.*)$/;
168
- const ruleMembersRegExp = /^(?<index>\d+)\) BP_Ruleset_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.MemberStates =$/;
169
- const teamNameRegExp = /^(?<index>\d+)\) BP_Team(_\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.(?<team>BP_Team(_\w+)?_C_\d+)\.TeamName = (?<name>.*)$/;
170
- const teamColorRegExp = /^(?<index>\d+)\) BP_Team(_\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.(?<team>BP_Team(_\w+)?_C_\d+)\.TeamColor = \(B=(?<b>\d+),G=(?<g>\d+),R=(?<r>\d+),A=(?<a>\d+)\)$/;
171
- const teamMembersRegExp = /^(?<index>\d+)\) BP_Team(_\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.(?<team>BP_Team(_\w+)?_C_\d+)\.MemberStates =$/;
172
- const playerStateRegExp = /^\t(?<index>\d+): .*?BP_PlayerState_C'(.+):PersistentLevel\.(?<state>BP_PlayerState_C_\d+)'$/;
173
- try {
174
- // parse console output to get the minigame info
175
- const [rulesets, ruleMembers, teamMembers, teamNames, teamColors] = await Promise.all([
176
- this.watchLogChunk('GetAll BP_Ruleset_C RulesetName', ruleNameRegExp, {
177
- first: 'index',
178
- }),
179
- this.watchLogArray('GetAll BP_Ruleset_C MemberStates', ruleMembersRegExp, playerStateRegExp),
180
- this.watchLogArray('GetAll BP_Team_C MemberStates', teamMembersRegExp, playerStateRegExp),
181
- this.watchLogChunk('GetAll BP_Team_C TeamName', teamNameRegExp, {
182
- first: 'index',
183
- }),
184
- // team color in a5 is based on (B=255,G=255,R=255,A=255)
185
- this.watchLogChunk('GetAll BP_Team_C TeamColor', teamColorRegExp, {
186
- first: 'index',
187
- }),
188
- ]);
189
- // figure out what to do with the matched color results
190
- const handleColor = (match) => {
191
- // color index, return the colorset color
192
- if ('color' in match)
193
- return _util_1.color.DEFAULT_COLORSET[Number(match)].slice();
194
- else
195
- return [match.r, match.g, match.b, match.a].map(Number);
196
- };
197
- const sortedRulesets = rulesets.sort((a, b) => { var _a, _b; return (_a = b.groups) === null || _a === void 0 ? void 0 : _a.ruleset.localeCompare((_b = a.groups) === null || _b === void 0 ? void 0 : _b.ruleset); });
198
- const globalIndex = rulesets.findIndex(ruleset => { var _a; return ((_a = ruleset.groups) === null || _a === void 0 ? void 0 : _a.name) === 'GLOBAL'; });
199
- const indexMap = Object.fromEntries(sortedRulesets.map((ruleset, index) => {
200
- var _a;
201
- if (globalIndex > -1) {
202
- if (index > globalIndex) {
203
- index = index - 1;
204
- }
205
- else if (index === globalIndex) {
206
- index = -1;
207
- }
208
- }
209
- return [(_a = ruleset.groups) === null || _a === void 0 ? void 0 : _a.ruleset, index];
210
- }));
211
- // join the data into a big object
212
- return rulesets.map(r => ({
213
- name: r.groups.name,
214
- ruleset: r.groups.ruleset,
215
- index: indexMap[r.groups.ruleset],
216
- // get the players from the team members
217
- members: ruleMembers
218
- .find(m => m.item.ruleset === r.groups.ruleset)
219
- .members // get the members from this ruleset
220
- .map(m => this.getPlayer(m.state))
221
- .filter(Boolean), // get the players
222
- // get the teams for this ruleset
223
- teams: teamMembers
224
- .filter(m => m.item.ruleset === r.groups.ruleset) // only get teams from this ruleset
225
- .map(m => {
226
- var _a, _b;
227
- return ({
228
- // team name
229
- name: lodash_1.default.get(teamNames.find(t => t.groups.team === m.item.team), 'groups.name'),
230
- team: m.item.team,
231
- // get the colors (different for a4 and a5)
232
- color: handleColor(lodash_1.default.pick((_b = (_a = teamColors.find(t => t.groups.team === m.item.team)) === null || _a === void 0 ? void 0 : _a.groups) !== null && _b !== void 0 ? _b : {
233
- r: 0,
234
- g: 0,
235
- b: 0,
236
- a: 0,
237
- }, ['r', 'g', 'b', 'a'])),
238
- // get the players from the team
239
- members: m.members
240
- .map(m => this.getPlayer(m.state))
241
- .filter(Boolean),
242
- });
243
- }),
244
- }));
53
+ })
54
+ };
55
+ return status;
56
+ },
57
+ /**
58
+ * Get a list of minigames
59
+ * @return Minigame List
60
+ */
61
+ async listMinigames() {
62
+ const minigameLines = await this.watchLogChunk(
63
+ "Server.Minigames.List",
64
+ /^LogConsoleCommands: (.+)$/,
65
+ {
66
+ first: (match) => match[1].startsWith("Minigame Count:"),
67
+ timeoutDelay: 1e3
68
+ }
69
+ );
70
+ const [tableHeader, ...tableLines] = minigameLines.filter((l) => l[1].startsWith("* ")).map((l) => l[1].slice(1));
71
+ const columnRegExp = buildTableHeaderRegex(tableHeader);
72
+ return tableLines.map((l) => {
73
+ const {
74
+ groups: { id, name, ownername, ownerid, member }
75
+ } = l.match(columnRegExp);
76
+ return {
77
+ index: Number(id),
78
+ name: name.trim(),
79
+ numMembers: Number(member),
80
+ owner: { name: ownername.trim(), id: ownerid }
81
+ };
82
+ });
83
+ },
84
+ // async getAllPawnData<T extends PawnDataField<string, any>[]>(
85
+ // fields: T
86
+ // ): Promise<{
87
+ // controller: string;
88
+ // data: FromEntriesDataField<[PawnDataField<'pawn', string>, ...T]>;
89
+ // }> {
90
+ // const restFields: [PawnDataField<'pawn', string>, ...T] = [
91
+ // {
92
+ // command: 'GetAll BP_PlayerController_C Pawn',
93
+ // object: 'BP_PlayerController_C',
94
+ // objectMatcher: /(?<controller>BP_PlayerController_C_\d+)/,
95
+ // objectField: 'Pawn',
96
+ // valueMatcher:
97
+ // /(?:None|BP_FigureV2_C'.+?:PersistentLevel.(?<pawn>BP_FigureV2_C_\d+)')?$/,
98
+ // valueTransform: matches => matches.groups.pawn ?? null,
99
+ // field: 'pawn',
100
+ // } as PawnDataField<'pawn', string>,
101
+ // ...fields,
102
+ // ];
103
+ // return {
104
+ // controller: 'test',
105
+ // data: Object.fromEntries(
106
+ // restFields.map(f => [
107
+ // f.field,
108
+ // f.valueTransform({ groups: { pawn: 'foo' } } as any),
109
+ // ])
110
+ // ) as FromEntriesDataField<[PawnDataField<'pawn', string>, ...T]>,
111
+ // };
112
+ // },
113
+ /**
114
+ * get every player's position and alive states
115
+ */
116
+ async getAllPlayerPositions() {
117
+ const pawnRegExp = /(?<index>\d+)\) BP_PlayerController_C .+?PersistentLevel\.(?<controller>BP_PlayerController_C_\d+)\.Pawn = .*?(?:None|BP_FigureV2_C'.+?:PersistentLevel.(?<pawn>BP_FigureV2_C_\d+)')?$/;
118
+ const posRegExp = /(?<index>\d+)\) CapsuleComponent .+?PersistentLevel\.(?<pawn>BP_FigureV2_C_\d+)\.CollisionCylinder\.RelativeLocation = \(X=(?<x>[\d.-]+),Y=(?<y>[\d.-]+),Z=(?<z>[\d.-]+)\)$/;
119
+ const deadFigureRegExp = /(?<index>\d+)\) BP_FigureV2_C .+?PersistentLevel\.(?<pawn>BP_FigureV2_C_\d+)\.bIsDead = (?<dead>(True|False))$/;
120
+ const [pawns, deadFigures, positions] = await Promise.all([
121
+ this.watchLogChunk(
122
+ "GetAll BP_PlayerController_C Pawn",
123
+ pawnRegExp,
124
+ {
125
+ first: "index",
126
+ timeoutDelay: 250
245
127
  }
246
- catch (e) {
247
- logger_1.default.error('error getting minigames', e);
248
- return undefined;
128
+ ),
129
+ this.watchLogChunk(
130
+ "GetAll BP_FigureV2_C bIsDead",
131
+ deadFigureRegExp,
132
+ {
133
+ first: "index",
134
+ timeoutDelay: 250
249
135
  }
250
- },
251
- };
252
- // inject the commands into the object given a log wrangler
253
- exports.default = (obj, logWrangler) => {
254
- for (const cmd in COMMANDS) {
255
- // disgusting type casting because we're injecting functions
256
- obj[cmd] =
257
- COMMANDS[cmd].bind(logWrangler);
136
+ ),
137
+ this.watchLogChunk(
138
+ "GetAll SceneComponent RelativeLocation Name=CollisionCylinder",
139
+ posRegExp,
140
+ { first: "index", timeoutDelay: 250 }
141
+ )
142
+ ]);
143
+ return pawns.map((pawn) => ({
144
+ // find the player for the associated controller
145
+ player: this.getPlayer(pawn.groups.controller),
146
+ // find the position for the associated pawn
147
+ pos: positions.find((pos) => pawn.groups.pawn === pos.groups.pawn),
148
+ isDead: deadFigures.find(
149
+ (dead) => pawn.groups.pawn === dead.groups.pawn
150
+ ),
151
+ pawn
152
+ })).filter((p) => p.player).map((p) => ({
153
+ player: p.player,
154
+ pawn: p.pawn.groups.pawn || null,
155
+ pos: p.pos ? p.pos.slice(3).map(Number) : null,
156
+ isDead: p.isDead ? p.isDead.groups.dead === "True" : true
157
+ }));
158
+ },
159
+ /**
160
+ * get all minigames and their players (and the player's teams)
161
+ */
162
+ async getMinigames() {
163
+ const ruleNameRegExp = /^(?<index>\d+)\) BP_Ruleset_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.RulesetName = (?<name>.*)$/;
164
+ const ruleMembersRegExp = /^(?<index>\d+)\) BP_Ruleset_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.MemberStates =$/;
165
+ const teamNameRegExp = /^(?<index>\d+)\) BP_Team(_\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.(?<team>BP_Team(_\w+)?_C_\d+)\.TeamName = (?<name>.*)$/;
166
+ const teamColorRegExp = /^(?<index>\d+)\) BP_Team(_\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.(?<team>BP_Team(_\w+)?_C_\d+)\.TeamColor = \(B=(?<b>\d+),G=(?<g>\d+),R=(?<r>\d+),A=(?<a>\d+)\)$/;
167
+ const teamMembersRegExp = /^(?<index>\d+)\) BP_Team(_\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\d+)\.(?<team>BP_Team(_\w+)?_C_\d+)\.MemberStates =$/;
168
+ const playerStateRegExp = /^\t(?<index>\d+): .*?BP_PlayerState_C'(.+):PersistentLevel\.(?<state>BP_PlayerState_C_\d+)'$/;
169
+ try {
170
+ const [rulesets, ruleMembers, teamMembers, teamNames, teamColors] = await Promise.all([
171
+ this.watchLogChunk(
172
+ "GetAll BP_Ruleset_C RulesetName",
173
+ ruleNameRegExp,
174
+ {
175
+ first: "index"
176
+ }
177
+ ),
178
+ this.watchLogArray(
179
+ "GetAll BP_Ruleset_C MemberStates",
180
+ ruleMembersRegExp,
181
+ playerStateRegExp
182
+ ),
183
+ this.watchLogArray(
184
+ "GetAll BP_Team_C MemberStates",
185
+ teamMembersRegExp,
186
+ playerStateRegExp
187
+ ),
188
+ this.watchLogChunk(
189
+ "GetAll BP_Team_C TeamName",
190
+ teamNameRegExp,
191
+ {
192
+ first: "index"
193
+ }
194
+ ),
195
+ // team color in a5 is based on (B=255,G=255,R=255,A=255)
196
+ this.watchLogChunk(
197
+ "GetAll BP_Team_C TeamColor",
198
+ teamColorRegExp,
199
+ {
200
+ first: "index"
201
+ }
202
+ )
203
+ ]);
204
+ const handleColor = (match) => {
205
+ if ("color" in match)
206
+ return index.color.DEFAULT_COLORSET[Number(match)].slice();
207
+ else return [match.r, match.g, match.b, match.a].map(Number);
208
+ };
209
+ const sortedRulesets = rulesets.sort(
210
+ (a, b) => b.groups?.ruleset.localeCompare(a.groups?.ruleset)
211
+ );
212
+ const globalIndex = rulesets.findIndex(
213
+ (ruleset) => ruleset.groups?.name === "GLOBAL"
214
+ );
215
+ const indexMap = Object.fromEntries(
216
+ sortedRulesets.map((ruleset, index2) => {
217
+ if (globalIndex > -1) {
218
+ if (index2 > globalIndex) {
219
+ index2 = index2 - 1;
220
+ } else if (index2 === globalIndex) {
221
+ index2 = -1;
222
+ }
223
+ }
224
+ return [ruleset.groups?.ruleset, index2];
225
+ })
226
+ );
227
+ return rulesets.map((r) => ({
228
+ name: r.groups.name,
229
+ ruleset: r.groups.ruleset,
230
+ index: indexMap[r.groups.ruleset],
231
+ // get the players from the team members
232
+ members: ruleMembers.find((m) => m.item.ruleset === r.groups.ruleset).members.map((m) => this.getPlayer(m.state)).filter(Boolean),
233
+ // get the players
234
+ // get the teams for this ruleset
235
+ teams: teamMembers.filter((m) => m.item.ruleset === r.groups.ruleset).map((m) => ({
236
+ // team name
237
+ name: _.get(
238
+ teamNames.find((t) => t.groups.team === m.item.team),
239
+ "groups.name"
240
+ ),
241
+ team: m.item.team,
242
+ // get the colors (different for a4 and a5)
243
+ color: handleColor(
244
+ _.pick(
245
+ teamColors.find((t) => t.groups.team === m.item.team)?.groups ?? {
246
+ r: 0,
247
+ g: 0,
248
+ b: 0,
249
+ a: 0
250
+ },
251
+ ["r", "g", "b", "a"]
252
+ )
253
+ ),
254
+ // get the players from the team
255
+ members: m.members.map((m2) => this.getPlayer(m2.state)).filter(Boolean)
256
+ }))
257
+ }));
258
+ } catch (e) {
259
+ logger.default.error("error getting minigames", e);
260
+ return void 0;
258
261
  }
262
+ }
263
+ };
264
+ const commandInjector = (obj, logWrangler) => {
265
+ for (const cmd in COMMANDS) {
266
+ obj[cmd] = COMMANDS[cmd].bind(logWrangler);
267
+ }
259
268
  };
260
- //# sourceMappingURL=commandInjector.js.map
269
+ exports.default = commandInjector;
270
+ //# sourceMappingURL=commandInjector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commandInjector.js","sourceRoot":"","sources":["../../src/omegga/commandInjector.ts"],"names":[],"mappings":";;;;;AAAA,oDAAuB;AACvB,mCAAoC;AASpC,uDAA8B;AAmD9B,MAAM,qBAAqB,GAAG,CAAC,MAAc,EAAE,EAAE;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,IAAI,MAAM,CACf,OAAO,CAAC,mCAAmC;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAChB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACjD,CAAC,CAAC,gDAAgD;SAClD,GAAG,CACF,CAAC,CAAC,IAAI,EAAE,GAAG,CAAmB,EAAE,EAAE,CAChC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CACrD,CAAC,8FAA8F;SAC/F,IAAI,CAAC,KAAK,CAAC,CACf,CAAC,CAAC,8BAA8B;AACnC,CAAC,CAAC;AACF,0EAA0E;AAC1E;;GAEG;AACH,MAAM,QAAQ,GAAqB;IACjC;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,WAAW,GAAG,MAClB,IACD,CAAC,aAAa,CACb,eAAe,EACf,4BAA4B,EAC5B;YACE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC;YACnD,YAAY,EAAE,IAAI;SACnB,CACF,CAAC;QAEF,sCAAsC;QACtC,gDAAgD;QAChD,MAAM,CAAC,WAAW,EAAE,GAAG,UAAU,CAAC,GAAG,WAAW;aAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3B,qEAAqE;QACrE,MAAM,YAAY,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG;YACb,uDAAuD;YACvD,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC7D,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC9D,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;YACrE,IAAI,EAAE,YAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,kDAAkD;YAClD,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBAC1B,gDAAgD;gBAChD,MAAM,EACJ,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,GACzD,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gBAC1B,kCAAkC;gBAClC,OAAO;oBACL,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;oBACjB,IAAI,EAAE,YAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACrC,IAAI,EAAE,YAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;oBACvC,KAAK,EAAE,KAAK;yBACT,IAAI,EAAE;yBACN,KAAK,CAAC,IAAI,CAAC;yBACX,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,0BAA0B;oBACxD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE;oBAC9C,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE;iBACd,CAAC;YACJ,CAAC,CAAC;SACH,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,aAAa,GAAG,MACpB,IACD,CAAC,aAAa,CACb,uBAAuB,EACvB,4BAA4B,EAC5B;YACE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC;YACtD,YAAY,EAAE,IAAI;SACnB,CACF,CAAC;QAEF,sCAAsC;QACtC,gDAAgD;QAChD,MAAM,CAAC,WAAW,EAAE,GAAG,UAAU,CAAC,GAAG,aAAa;aAC/C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3B,qEAAqE;QACrE,MAAM,YAAY,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAExD,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YACxB,gDAAgD;YAChD,MAAM,EACJ,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,GACjD,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC1B,kCAAkC;YAClC,OAAO;gBACL,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;gBACjB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;gBACjB,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;gBAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;aAC/C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gEAAgE;IAChE,cAAc;IACd,eAAe;IACf,wBAAwB;IACxB,uEAAuE;IACvE,OAAO;IACP,gEAAgE;IAChE,QAAQ;IACR,sDAAsD;IACtD,yCAAyC;IACzC,mEAAmE;IACnE,6BAA6B;IAC7B,sBAAsB;IACtB,sFAAsF;IACtF,gEAAgE;IAChE,uBAAuB;IACvB,0CAA0C;IAC1C,iBAAiB;IACjB,OAAO;IAEP,aAAa;IACb,0BAA0B;IAC1B,gCAAgC;IAChC,8BAA8B;IAC9B,mBAAmB;IACnB,gEAAgE;IAChE,WAAW;IACX,wEAAwE;IACxE,OAAO;IACP,KAAK;IAEL;;OAEG;IACH,KAAK,CAAC,qBAAqB;QACzB,MAAM,UAAU,GACd,wLAAwL,CAAC;QAC3L,MAAM,SAAS,GACb,6KAA6K,CAAC;QAChL,MAAM,gBAAgB,GACpB,gHAAgH,CAAC;QAEnH,oEAAoE;QACpE,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACxD,IAAI,CAAC,aAAa,CAChB,mCAAmC,EACnC,UAAU,EACV;gBACE,KAAK,EAAE,OAAO;gBACd,YAAY,EAAE,GAAG;aAClB,CACF;YACD,IAAI,CAAC,aAAa,CAChB,8BAA8B,EAC9B,gBAAgB,EAChB;gBACE,KAAK,EAAE,OAAO;gBACd,YAAY,EAAE,GAAG;aAClB,CACF;YACD,IAAI,CAAC,aAAa,CAChB,+DAA+D,EAC/D,SAAS,EACT,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,CACtC;SACF,CAAC,CAAC;QAEH,OAAO,CACL,KAAK;YACH,uCAAuC;aACtC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACZ,gDAAgD;YAChD,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YAC9C,4CAA4C;YAC5C,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YAChE,MAAM,EAAE,WAAW,CAAC,IAAI,CACtB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAC9C;YACD,IAAI;SACL,CAAC,CAAC;YACH,iKAAiK;aAChK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACtB,8EAA8E;aAC7E,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACT,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI;YAChC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;YAC9C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI;SAC1D,CAAC,CAAC,CACN,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,qCAAqC;QACrC,MAAM,cAAc,GAClB,6GAA6G,CAAC;QAChH,MAAM,iBAAiB,GACrB,kGAAkG,CAAC;QACrG,MAAM,cAAc,GAClB,6IAA6I,CAAC;QAChJ,MAAM,eAAe,GACnB,sLAAsL,CAAC;QACzL,MAAM,iBAAiB,GACrB,qIAAqI,CAAC;QACxI,MAAM,iBAAiB,GACrB,8FAA8F,CAAC;QAEjG,IAAI,CAAC;YACH,gDAAgD;YAChD,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,GAC/D,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,IAAI,CAAC,aAAa,CAChB,iCAAiC,EACjC,cAAc,EACd;oBACE,KAAK,EAAE,OAAO;iBACf,CACF;gBACD,IAAI,CAAC,aAAa,CAIhB,kCAAkC,EAClC,iBAAiB,EACjB,iBAAiB,CAClB;gBACD,IAAI,CAAC,aAAa,CAIhB,+BAA+B,EAC/B,iBAAiB,EACjB,iBAAiB,CAClB;gBACD,IAAI,CAAC,aAAa,CAChB,2BAA2B,EAC3B,cAAc,EACd;oBACE,KAAK,EAAE,OAAO;iBACf,CACF;gBACD,yDAAyD;gBACzD,IAAI,CAAC,aAAa,CAChB,4BAA4B,EAC5B,eAAe,EACf;oBACE,KAAK,EAAE,OAAO;iBACf,CACF;aACF,CAAC,CAAC;YAEL,uDAAuD;YACvD,MAAM,WAAW,GAAG,CAClB,KAEkD,EAClD,EAAE;gBACF,yCAAyC;gBACzC,IAAI,OAAO,IAAI,KAAK;oBAClB,OAAO,aAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;;oBAClD,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC/D,CAAC,CAAC;YAEF,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,eAC5C,OAAA,MAAA,CAAC,CAAC,MAAM,0CAAE,OAAO,CAAC,aAAa,CAAC,MAAA,CAAC,CAAC,MAAM,0CAAE,OAAO,CAAC,CAAA,EAAA,CACnD,CAAC;YACF,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CACpC,OAAO,CAAC,EAAE,WAAC,OAAA,CAAA,MAAA,OAAO,CAAC,MAAM,0CAAE,IAAI,MAAK,QAAQ,CAAA,EAAA,CAC7C,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CACjC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;;gBACpC,IAAI,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;oBACrB,IAAI,KAAK,GAAG,WAAW,EAAE,CAAC;wBACxB,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;oBACpB,CAAC;yBAAM,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;wBACjC,KAAK,GAAG,CAAC,CAAC,CAAC;oBACb,CAAC;gBACH,CAAC;gBAED,OAAO,CAAC,MAAA,OAAO,CAAC,MAAM,0CAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAC1C,CAAC,CAAC,CACH,CAAC;YAEF,kCAAkC;YAClC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACxB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI;gBACnB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO;gBACzB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBAEjC,wCAAwC;gBACxC,OAAO,EAAE,WAAW;qBACjB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;qBAC9C,OAAO,CAAC,oCAAoC;qBAC5C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;qBACjC,MAAM,CAAC,OAAO,CAAC,EAAE,kBAAkB;gBAEtC,iCAAiC;gBACjC,KAAK,EAAE,WAAW;qBACf,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,mCAAmC;qBACpF,GAAG,CAAC,CAAC,CAAC,EAAE;;oBAAC,OAAA,CAAC;wBACT,YAAY;wBACZ,IAAI,EAAE,gBAAC,CAAC,GAAG,CACT,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAClD,aAAa,CACJ;wBACX,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;wBAEjB,2CAA2C;wBAC3C,KAAK,EAAE,WAAW,CAChB,gBAAC,CAAC,IAAI,CACJ,MAAA,MAAA,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,0CAAE,MAAM,mCACxD;4BACC,CAAC,EAAE,CAAC;4BACJ,CAAC,EAAE,CAAC;4BACJ,CAAC,EAAE,CAAC;4BACJ,CAAC,EAAE,CAAC;yBACG,EACX,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CACrB,CACF;wBAED,gCAAgC;wBAChC,OAAO,EAAE,CAAC,CAAC,OAAO;6BACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;6BACjC,MAAM,CAAC,OAAO,CAAC;qBACnB,CAAC,CAAA;iBAAA,CAAC;aACN,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,gBAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;YAC3C,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;CACF,CAAC;AAEF,2DAA2D;AAC3D,kBAAe,CACb,GAAM,EACN,WAAwB,EACxB,EAAE;IACF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,4DAA4D;QAC3D,GAA2C,CAAC,GAAG,CAAC;YAC/C,QAAQ,CAAC,GAA4B,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"commandInjector.js","sources":["../../src/omegga/commandInjector.ts"],"sourcesContent":["import _ from 'lodash';\nimport { color, time } from '@util';\nimport type LogWrangler from './logWrangler';\nimport {\n ILogMinigame,\n IMinigameList,\n IPlayerPositions,\n IServerStatus,\n} from './types';\nimport { InjectedCommands, OmeggaPlayer, OmeggaLike } from '@/plugin';\nimport Logger from '@/logger';\n\ntype Cast<X, Y> = X extends Y ? X : Y;\ntype ArrayElement<A> = A extends readonly (infer T)[] ? T : never;\ntype Extract<T, U> = T extends U ? T : never;\ntype FromEntriesDataField<T> = T extends PawnDataField<infer Key, any>[]\n ? {\n [K in Cast<Key, string>]: ReturnType<\n Extract<ArrayElement<T>, PawnDataField<K, any>>['valueTransform']\n >;\n }\n : { [key in string]: any };\n\nexport type PawnDataField<F, T = string> = {\n /**\n * The command to execute and listen to.\n */\n command: string;\n\n /**\n * The game object name, like `BP_FigureV2_C`.\n */\n object: string;\n\n /**\n * What object should be matched, like `/(?<pawn>BP_FigureV2_C_\\d+)/`.\n */\n objectMatcher: RegExp;\n\n /**\n * The field on the game object, like `bIsDead`.\n */\n objectField: string;\n\n /**\n * The regex that should match the value of the game object field.\n * If `valueTransform` is not specified, `value` becomes the first capture group.\n */\n valueMatcher: RegExp;\n\n /**\n * An optional closure to transform what `valueMatcher` matched.\n */\n valueTransform?: (match: RegExpMatchArray) => T;\n\n /**\n * The field on the final object.\n */\n field: F;\n};\n\nconst buildTableHeaderRegex = (header: string) => {\n const columns = header.match(/[^|]+/g);\n return new RegExp(\n columns // get all strings between the |'s'\n .map((line, i) => [\n line.slice(1, -1),\n line.length - (i === columns.length - 1 ? 1 : 2),\n ]) // calculate the lengths (and remove the spaces)\n .map(\n ([name, len]: [string, number]) =>\n ` (?<${name.trim().toLowerCase()}>.{${len}})( |$)`,\n ) // create a regex pattern to match strings of that length (and trim off whitespace at the end)\n .join('\\\\|'),\n ); // join the regexes with the |\n};\n// A list of commands that can be injected to things with the log wrangler\n/**\n * List of injected commands\n */\nconst COMMANDS: InjectedCommands = {\n /**\n * Get a server status object containing bricks, time, players, player ping, player roles, etc\n */\n async getServerStatus(): Promise<IServerStatus> {\n const statusLines = await (\n this as OmeggaLike\n ).watchLogChunk<RegExpMatchArray>(\n 'Server.Status',\n /^LogConsoleCommands: (.+)$/,\n {\n first: match => match[1].startsWith('Server Name:'),\n timeoutDelay: 1000,\n },\n );\n\n // the table lines all start with '* '\n // find all those lines, and remove the asterisk\n const [tableHeader, ...tableLines] = statusLines\n .filter(l => l[1].startsWith('* '))\n .map(l => l[1].slice(1));\n\n // use the size of each column to build a regex that matches each row\n const columnRegExp = buildTableHeaderRegex(tableHeader);\n\n const status = {\n // easily extract certain values from the server status\n serverName: statusLines[0][1].match(/^Server Name: (.*)$/)[1],\n description: statusLines[1][1].match(/^Description: (.*)$/)[1],\n bricks: Number(statusLines[2][1].match(/^Bricks: (\\d+)$/)[1]),\n components: Number(statusLines[3][1].match(/^Components: (\\d+)$/)[1]),\n time: time.parseDuration(statusLines[4][1].match(/^Time: (.*)$/)[1]),\n // extract players using the generated table regex\n players: tableLines.map(l => {\n // match the player row with the generated regex\n const {\n groups: { name, ping, time: online, roles, address, id },\n } = l.match(columnRegExp);\n // trim and parse the matched data\n return {\n name: name.trim(),\n ping: time.parseDuration(ping.trim()),\n time: time.parseDuration(online.trim()),\n roles: roles\n .trim()\n .split(', ')\n .filter(r => r.length > 0), // roles are split by ', '\n address: address.replace('(Owner)', '').trim(),\n id: id.trim(),\n };\n }),\n };\n\n return status;\n },\n\n /**\n * Get a list of minigames\n * @return Minigame List\n */\n async listMinigames(): Promise<IMinigameList> {\n const minigameLines = await (\n this as OmeggaLike\n ).watchLogChunk<RegExpMatchArray>(\n 'Server.Minigames.List',\n /^LogConsoleCommands: (.+)$/,\n {\n first: match => match[1].startsWith('Minigame Count:'),\n timeoutDelay: 1000,\n },\n );\n\n // the table lines all start with '* '\n // find all those lines, and remove the asterisk\n const [tableHeader, ...tableLines] = minigameLines\n .filter(l => l[1].startsWith('* '))\n .map(l => l[1].slice(1));\n\n // use the size of each column to build a regex that matches each row\n const columnRegExp = buildTableHeaderRegex(tableHeader);\n\n return tableLines.map(l => {\n // match the player row with the generated regex\n const {\n groups: { id, name, ownername, ownerid, member },\n } = l.match(columnRegExp);\n // trim and parse the matched data\n return {\n index: Number(id),\n name: name.trim(),\n numMembers: Number(member),\n owner: { name: ownername.trim(), id: ownerid },\n };\n });\n },\n\n // async getAllPawnData<T extends PawnDataField<string, any>[]>(\n // fields: T\n // ): Promise<{\n // controller: string;\n // data: FromEntriesDataField<[PawnDataField<'pawn', string>, ...T]>;\n // }> {\n // const restFields: [PawnDataField<'pawn', string>, ...T] = [\n // {\n // command: 'GetAll BP_PlayerController_C Pawn',\n // object: 'BP_PlayerController_C',\n // objectMatcher: /(?<controller>BP_PlayerController_C_\\d+)/,\n // objectField: 'Pawn',\n // valueMatcher:\n // /(?:None|BP_FigureV2_C'.+?:PersistentLevel.(?<pawn>BP_FigureV2_C_\\d+)')?$/,\n // valueTransform: matches => matches.groups.pawn ?? null,\n // field: 'pawn',\n // } as PawnDataField<'pawn', string>,\n // ...fields,\n // ];\n\n // return {\n // controller: 'test',\n // data: Object.fromEntries(\n // restFields.map(f => [\n // f.field,\n // f.valueTransform({ groups: { pawn: 'foo' } } as any),\n // ])\n // ) as FromEntriesDataField<[PawnDataField<'pawn', string>, ...T]>,\n // };\n // },\n\n /**\n * get every player's position and alive states\n */\n async getAllPlayerPositions(): Promise<IPlayerPositions> {\n const pawnRegExp =\n /(?<index>\\d+)\\) BP_PlayerController_C .+?PersistentLevel\\.(?<controller>BP_PlayerController_C_\\d+)\\.Pawn = .*?(?:None|BP_FigureV2_C'.+?:PersistentLevel.(?<pawn>BP_FigureV2_C_\\d+)')?$/;\n const posRegExp =\n /(?<index>\\d+)\\) CapsuleComponent .+?PersistentLevel\\.(?<pawn>BP_FigureV2_C_\\d+)\\.CollisionCylinder\\.RelativeLocation = \\(X=(?<x>[\\d.-]+),Y=(?<y>[\\d.-]+),Z=(?<z>[\\d.-]+)\\)$/;\n const deadFigureRegExp =\n /(?<index>\\d+)\\) BP_FigureV2_C .+?PersistentLevel\\.(?<pawn>BP_FigureV2_C_\\d+)\\.bIsDead = (?<dead>(True|False))$/;\n\n // wait for the pawn and position watchers to return all the results\n const [pawns, deadFigures, positions] = await Promise.all([\n this.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_PlayerController_C Pawn',\n pawnRegExp,\n {\n first: 'index',\n timeoutDelay: 250,\n },\n ),\n this.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_FigureV2_C bIsDead',\n deadFigureRegExp,\n {\n first: 'index',\n timeoutDelay: 250,\n },\n ),\n this.watchLogChunk<RegExpMatchArray>(\n 'GetAll SceneComponent RelativeLocation Name=CollisionCylinder',\n posRegExp,\n { first: 'index', timeoutDelay: 250 },\n ),\n ]);\n\n return (\n pawns\n // iterate through the pawn+controllers\n .map(pawn => ({\n // find the player for the associated controller\n player: this.getPlayer(pawn.groups.controller),\n // find the position for the associated pawn\n pos: positions.find(pos => pawn.groups.pawn === pos.groups.pawn),\n isDead: deadFigures.find(\n dead => pawn.groups.pawn === dead.groups.pawn,\n ),\n pawn,\n }))\n // filter by only those who have both player. previously we filtered by position but this breaks for players without a pawn, instead it's preferable to pass null\n .filter(p => p.player)\n // turn the position into a [x, y, z] number array (last 3 items in the array)\n .map(p => ({\n player: p.player,\n pawn: p.pawn.groups.pawn || null,\n pos: p.pos ? p.pos.slice(3).map(Number) : null,\n isDead: p.isDead ? p.isDead.groups.dead === 'True' : true,\n }))\n );\n },\n\n /**\n * get all minigames and their players (and the player's teams)\n */\n async getMinigames(): Promise<ILogMinigame[]> {\n // patterns to match the console logs\n const ruleNameRegExp =\n /^(?<index>\\d+)\\) BP_Ruleset_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\\d+)\\.RulesetName = (?<name>.*)$/;\n const ruleMembersRegExp =\n /^(?<index>\\d+)\\) BP_Ruleset_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\\d+)\\.MemberStates =$/;\n const teamNameRegExp =\n /^(?<index>\\d+)\\) BP_Team(_\\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\\d+)\\.(?<team>BP_Team(_\\w+)?_C_\\d+)\\.TeamName = (?<name>.*)$/;\n const teamColorRegExp =\n /^(?<index>\\d+)\\) BP_Team(_\\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\\d+)\\.(?<team>BP_Team(_\\w+)?_C_\\d+)\\.TeamColor = \\(B=(?<b>\\d+),G=(?<g>\\d+),R=(?<r>\\d+),A=(?<a>\\d+)\\)$/;\n const teamMembersRegExp =\n /^(?<index>\\d+)\\) BP_Team(_\\w+)?_C (.+):PersistentLevel.(?<ruleset>BP_Ruleset_C_\\d+)\\.(?<team>BP_Team(_\\w+)?_C_\\d+)\\.MemberStates =$/;\n const playerStateRegExp =\n /^\\t(?<index>\\d+): .*?BP_PlayerState_C'(.+):PersistentLevel\\.(?<state>BP_PlayerState_C_\\d+)'$/;\n\n try {\n // parse console output to get the minigame info\n const [rulesets, ruleMembers, teamMembers, teamNames, teamColors] =\n await Promise.all([\n this.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_Ruleset_C RulesetName',\n ruleNameRegExp,\n {\n first: 'index',\n },\n ),\n this.watchLogArray<\n { index: string; ruleset: string },\n { index: string; state: string }\n >(\n 'GetAll BP_Ruleset_C MemberStates',\n ruleMembersRegExp,\n playerStateRegExp,\n ),\n this.watchLogArray<\n { index: string; ruleset: string; team: string },\n { index: string; state: string }\n >(\n 'GetAll BP_Team_C MemberStates',\n teamMembersRegExp,\n playerStateRegExp,\n ),\n this.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_Team_C TeamName',\n teamNameRegExp,\n {\n first: 'index',\n },\n ),\n // team color in a5 is based on (B=255,G=255,R=255,A=255)\n this.watchLogChunk<RegExpMatchArray>(\n 'GetAll BP_Team_C TeamColor',\n teamColorRegExp,\n {\n first: 'index',\n },\n ),\n ]);\n\n // figure out what to do with the matched color results\n const handleColor = (\n match:\n | { color: string }\n | { r: string; g: string; b: string; a: string },\n ) => {\n // color index, return the colorset color\n if ('color' in match)\n return color.DEFAULT_COLORSET[Number(match)].slice();\n else return [match.r, match.g, match.b, match.a].map(Number);\n };\n\n const sortedRulesets = rulesets.sort((a, b) =>\n b.groups?.ruleset.localeCompare(a.groups?.ruleset),\n );\n const globalIndex = rulesets.findIndex(\n ruleset => ruleset.groups?.name === 'GLOBAL',\n );\n\n const indexMap = Object.fromEntries(\n sortedRulesets.map((ruleset, index) => {\n if (globalIndex > -1) {\n if (index > globalIndex) {\n index = index - 1;\n } else if (index === globalIndex) {\n index = -1;\n }\n }\n\n return [ruleset.groups?.ruleset, index];\n }),\n );\n\n // join the data into a big object\n return rulesets.map(r => ({\n name: r.groups.name,\n ruleset: r.groups.ruleset,\n index: indexMap[r.groups.ruleset],\n\n // get the players from the team members\n members: ruleMembers\n .find(m => m.item.ruleset === r.groups.ruleset)\n .members // get the members from this ruleset\n .map(m => this.getPlayer(m.state))\n .filter(Boolean), // get the players\n\n // get the teams for this ruleset\n teams: teamMembers\n .filter(m => m.item.ruleset === r.groups.ruleset) // only get teams from this ruleset\n .map(m => ({\n // team name\n name: _.get(\n teamNames.find(t => t.groups.team === m.item.team),\n 'groups.name',\n ) as string,\n team: m.item.team,\n\n // get the colors (different for a4 and a5)\n color: handleColor(\n _.pick(\n teamColors.find(t => t.groups.team === m.item.team)?.groups ??\n ({\n r: 0,\n g: 0,\n b: 0,\n a: 0,\n } as any),\n ['r', 'g', 'b', 'a'],\n ),\n ),\n\n // get the players from the team\n members: m.members\n .map(m => this.getPlayer(m.state))\n .filter(Boolean),\n })),\n }));\n } catch (e) {\n Logger.error('error getting minigames', e);\n return undefined;\n }\n },\n};\n\n// inject the commands into the object given a log wrangler\nexport default <T extends InjectedCommands>(\n obj: T,\n logWrangler: LogWrangler,\n) => {\n for (const cmd in COMMANDS) {\n // disgusting type casting because we're injecting functions\n (obj as unknown as Record<string, Function>)[cmd] =\n COMMANDS[cmd as keyof typeof COMMANDS].bind(logWrangler);\n }\n};\n"],"names":["time","color","index","m","Logger"],"mappings":"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"}