steamutils 1.5.13 → 1.5.14

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 (233) hide show
  1. package/.idea/codeStyles/Project.xml +0 -1
  2. package/.idea/gbrowser_project.xml +11 -0
  3. package/.idea/git_toolbox_blame.xml +6 -0
  4. package/.idea/git_toolbox_prj.xml +15 -0
  5. package/.prettierrc.json +3 -3
  6. package/SteamClient.js +3129 -3129
  7. package/_steamproto.js +39 -39
  8. package/axios.js +84 -84
  9. package/bufferHelpers.js +115 -115
  10. package/cheerio.js +103 -103
  11. package/const.js +569 -569
  12. package/create_proto.js +96 -96
  13. package/full_steamproto.js +39 -39
  14. package/helpers/protos.js +48 -48
  15. package/index.js +7949 -7949
  16. package/package.json +2 -2
  17. package/protos/csgo/base_gcmessages.proto +553 -553
  18. package/protos/csgo/base_gcmessages_csgo.proto +547 -547
  19. package/protos/csgo/c_peer2peer_netmessages.proto +55 -55
  20. package/protos/csgo/clientmessages.proto +48 -48
  21. package/protos/csgo/connectionless_netmessages.proto +17 -17
  22. package/protos/csgo/cs_gameevents.proto +35 -35
  23. package/protos/csgo/cs_usercmd.proto +34 -34
  24. package/protos/csgo/cstrike15_usermessages.proto +592 -592
  25. package/protos/csgo/demo.proto +165 -165
  26. package/protos/csgo/econ_gcmessages.proto +219 -219
  27. package/protos/csgo/enums_clientserver.proto +1529 -1529
  28. package/protos/csgo/fatdemo.proto +125 -125
  29. package/protos/csgo/gameevents.proto +120 -120
  30. package/protos/csgo/gcsdk_gcmessages.proto +323 -323
  31. package/protos/csgo/gcsystemmsgs.proto +243 -243
  32. package/protos/csgo/netmessages.proto +618 -618
  33. package/protos/csgo/networkbasetypes.proto +246 -246
  34. package/protos/csgo/networksystem_protomessages.proto +17 -17
  35. package/protos/csgo/steamdatagram_messages_auth.proto +65 -65
  36. package/protos/csgo/steamdatagram_messages_sdr.proto +534 -534
  37. package/protos/csgo/steammessages_cloud.steamworkssdk.proto +68 -68
  38. package/protos/csgo/steammessages_gamenetworkingui.proto +61 -61
  39. package/protos/csgo/steammessages_helprequest.steamworkssdk.proto +22 -22
  40. package/protos/csgo/steammessages_oauth.steamworkssdk.proto +18 -18
  41. package/protos/csgo/steammessages_player.steamworkssdk.proto +254 -254
  42. package/protos/csgo/steammessages_publishedfile.steamworkssdk.proto +233 -233
  43. package/protos/csgo/steamnetworkingsockets_messages.proto +205 -205
  44. package/protos/csgo/steamnetworkingsockets_messages_certs.proto +39 -39
  45. package/protos/csgo/steamnetworkingsockets_messages_udp.proto +75 -75
  46. package/protos/csgo/te.proto +259 -259
  47. package/protos/csgo/uifontfile_format.proto +13 -13
  48. package/protos/csgo/usercmd.proto +39 -39
  49. package/protos/csgo/usermessages.proto +752 -752
  50. package/protos/google/protobuf/descriptor.proto +281 -281
  51. package/protos/steam/clientmetrics.proto +45 -45
  52. package/protos/steam/content_manifest.proto +62 -62
  53. package/protos/steam/contenthubs.proto +41 -41
  54. package/protos/steam/encrypted_app_ticket.proto +10 -10
  55. package/protos/steam/enums.proto +501 -501
  56. package/protos/steam/enums_clientserver.proto +1508 -1508
  57. package/protos/steam/enums_productinfo.proto +14 -14
  58. package/protos/steam/htmlmessages.proto +1039 -1039
  59. package/protos/steam/offline_ticket.proto +8 -8
  60. package/protos/steam/steamdatagram_messages_auth.proto +65 -65
  61. package/protos/steam/steamdatagram_messages_sdr.proto +533 -533
  62. package/protos/steam/steammessages_accounthardware.steamclient.proto +167 -167
  63. package/protos/steam/steammessages_appoverview.proto +204 -204
  64. package/protos/steam/steammessages_auth.steamclient.proto +375 -375
  65. package/protos/steam/steammessages_broadcast.steamclient.proto +618 -618
  66. package/protos/steam/steammessages_chat.steamclient.proto +1070 -1070
  67. package/protos/steam/steammessages_client_objects.proto +649 -649
  68. package/protos/steam/steammessages_clientlanp2p.proto +43 -43
  69. package/protos/steam/steammessages_clientmetrics.steamclient.proto +192 -192
  70. package/protos/steam/steammessages_clientnotificationtypes.proto +250 -250
  71. package/protos/steam/steammessages_clientserver.proto +392 -392
  72. package/protos/steam/steammessages_clientserver_2.proto +771 -771
  73. package/protos/steam/steammessages_clientserver_appinfo.proto +131 -131
  74. package/protos/steam/steammessages_clientserver_friends.proto +260 -260
  75. package/protos/steam/steammessages_clientserver_gameservers.proto +159 -159
  76. package/protos/steam/steammessages_clientserver_lbs.proto +70 -70
  77. package/protos/steam/steammessages_clientserver_login.proto +167 -167
  78. package/protos/steam/steammessages_clientserver_mms.proto +233 -233
  79. package/protos/steam/steammessages_clientserver_ucm.proto +207 -207
  80. package/protos/steam/steammessages_clientserver_uds.proto +125 -125
  81. package/protos/steam/steammessages_clientserver_ufs.proto +45 -45
  82. package/protos/steam/steammessages_clientserver_userstats.proto +80 -80
  83. package/protos/steam/steammessages_cloud.steamclient.proto +422 -422
  84. package/protos/steam/steammessages_contentsystem.steamclient.proto +123 -123
  85. package/protos/steam/steammessages_credentials.steamclient.proto +96 -96
  86. package/protos/steam/steammessages_datapublisher.steamclient.proto +102 -102
  87. package/protos/steam/steammessages_depotbuilder.steamclient.proto +99 -99
  88. package/protos/steam/steammessages_deviceauth.steamclient.proto +169 -169
  89. package/protos/steam/steammessages_econ.steamclient.proto +137 -137
  90. package/protos/steam/steammessages_familygroups.steamclient.proto +441 -441
  91. package/protos/steam/steammessages_friendmessages.steamclient.proto +141 -141
  92. package/protos/steam/steammessages_gamenetworking.steamclient.proto +25 -25
  93. package/protos/steam/steammessages_gamenetworkingui.proto +61 -61
  94. package/protos/steam/steammessages_gamenotifications.steamclient.proto +131 -131
  95. package/protos/steam/steammessages_gameservers.steamclient.proto +136 -136
  96. package/protos/steam/steammessages_hiddevices.proto +157 -157
  97. package/protos/steam/steammessages_inventory.steamclient.proto +172 -172
  98. package/protos/steam/steammessages_linkfilter.steamclient.proto +39 -39
  99. package/protos/steam/steammessages_lobbymatchmaking.steamclient.proto +29 -29
  100. package/protos/steam/steammessages_market.steamclient.proto +22 -22
  101. package/protos/steam/steammessages_marketingmessages.steamclient.proto +273 -273
  102. package/protos/steam/steammessages_offline.steamclient.proto +33 -33
  103. package/protos/steam/steammessages_parental.steamclient.proto +262 -262
  104. package/protos/steam/steammessages_parties.steamclient.proto +75 -75
  105. package/protos/steam/steammessages_partnerapps.steamclient.proto +106 -106
  106. package/protos/steam/steammessages_player.steamclient.proto +915 -915
  107. package/protos/steam/steammessages_publishedfile.steamclient.proto +737 -737
  108. package/protos/steam/steammessages_qms.steamclient.proto +111 -111
  109. package/protos/steam/steammessages_remoteclient.proto +100 -100
  110. package/protos/steam/steammessages_remoteclient_discovery.proto +244 -244
  111. package/protos/steam/steammessages_remoteclient_service.steamclient.proto +31 -31
  112. package/protos/steam/steammessages_remoteclient_service_messages.proto +217 -217
  113. package/protos/steam/steammessages_remoteplay.proto +975 -975
  114. package/protos/steam/steammessages_secrets.steamclient.proto +35 -35
  115. package/protos/steam/steammessages_shader.steamclient.proto +89 -89
  116. package/protos/steam/steammessages_site_license.steamclient.proto +103 -103
  117. package/protos/steam/steammessages_sitelicenseclient.proto +38 -38
  118. package/protos/steam/steammessages_siteserverui.proto +130 -130
  119. package/protos/steam/steammessages_steamtv.steamclient.proto +533 -533
  120. package/protos/steam/steammessages_store.steamclient.proto +404 -404
  121. package/protos/steam/steammessages_storebrowse.steamclient.proto +457 -457
  122. package/protos/steam/steammessages_timedtrial.steamclient.proto +40 -40
  123. package/protos/steam/steammessages_twofactor.steamclient.proto +157 -157
  124. package/protos/steam/steammessages_unified_test.steamclient.proto +51 -51
  125. package/protos/steam/steammessages_useraccount.steamclient.proto +211 -211
  126. package/protos/steam/steammessages_vac.steamclient.proto +37 -37
  127. package/protos/steam/steammessages_video.steamclient.proto +68 -68
  128. package/protos/steam/steammessages_virtualcontroller.proto +138 -138
  129. package/protos/steam/steammessages_workshop.steamclient.proto +19 -19
  130. package/protos/steam/steamnetworkingsockets_messages.proto +205 -205
  131. package/protos/steam/steamnetworkingsockets_messages_certs.proto +39 -39
  132. package/protos/steam/steamnetworkingsockets_messages_udp.proto +75 -75
  133. package/protos/steam/webuimessages_achievements.proto +29 -29
  134. package/protos/steam/webuimessages_gamenotes.proto +21 -21
  135. package/protos/steam/webuimessages_gamescope.proto +57 -57
  136. package/protos/steam/webuimessages_steamengine.proto +41 -41
  137. package/protos/steam/webuimessages_steamos.proto +114 -114
  138. package/protos/steam/webuimessages_storagedevicemanager.proto +110 -110
  139. package/protos/steam/webuimessages_systemmanager.proto +17 -17
  140. package/protos/steam/webuimessages_transport.proto +22 -22
  141. package/protos/steam/webuimessages_transportvalidation.proto +111 -111
  142. package/protos/webui/common.proto +4024 -4024
  143. package/protos/webui/service_accountcart.proto +153 -153
  144. package/protos/webui/service_accountlinking.proto +27 -27
  145. package/protos/webui/service_accountprivacy.proto +42 -42
  146. package/protos/webui/service_accountprivateapps.proto +34 -34
  147. package/protos/webui/service_auction.proto +97 -97
  148. package/protos/webui/service_authentication.proto +222 -222
  149. package/protos/webui/service_authenticationsupport.proto +74 -74
  150. package/protos/webui/service_broadcast.proto +562 -562
  151. package/protos/webui/service_chat.proto +11 -11
  152. package/protos/webui/service_chatroom.proto +810 -810
  153. package/protos/webui/service_chatusability.proto +107 -107
  154. package/protos/webui/service_checkout.proto +84 -84
  155. package/protos/webui/service_clan.proto +41 -41
  156. package/protos/webui/service_clanchatrooms.proto +25 -25
  157. package/protos/webui/service_clanfaqs.proto +202 -202
  158. package/protos/webui/service_clientcomm.proto +151 -151
  159. package/protos/webui/service_clientmetrics.proto +22 -22
  160. package/protos/webui/service_cloud.proto +222 -222
  161. package/protos/webui/service_cloudconfigstore.proto +51 -51
  162. package/protos/webui/service_cloudgaming.proto +30 -30
  163. package/protos/webui/service_community.proto +365 -365
  164. package/protos/webui/service_dailydeal.proto +89 -89
  165. package/protos/webui/service_econ.proto +134 -134
  166. package/protos/webui/service_embedded.proto +24 -24
  167. package/protos/webui/service_experimentservice.proto +6 -6
  168. package/protos/webui/service_familygroups.proto +355 -355
  169. package/protos/webui/service_fovasvideo.proto +15 -15
  170. package/protos/webui/service_friendmessages.proto +133 -133
  171. package/protos/webui/service_friendslist.proto +70 -70
  172. package/protos/webui/service_gamenotes.proto +15 -15
  173. package/protos/webui/service_gamerecording.proto +265 -265
  174. package/protos/webui/service_gamerecordingclip.proto +85 -85
  175. package/protos/webui/service_gamerecordingdebug.proto +52 -52
  176. package/protos/webui/service_helprequestlogs.proto +16 -16
  177. package/protos/webui/service_loyaltyrewards.proto +252 -252
  178. package/protos/webui/service_marketingmessages.proto +215 -215
  179. package/protos/webui/service_mobileapp.proto +18 -18
  180. package/protos/webui/service_mobileauth.proto +24 -24
  181. package/protos/webui/service_mobiledevice.proto +26 -26
  182. package/protos/webui/service_mobileperaccount.proto +31 -31
  183. package/protos/webui/service_news.proto +110 -110
  184. package/protos/webui/service_parental.proto +258 -258
  185. package/protos/webui/service_partnermembershipinvite.proto +34 -34
  186. package/protos/webui/service_partnerstorebrowse.proto +28 -28
  187. package/protos/webui/service_phone.proto +51 -51
  188. package/protos/webui/service_physicalgoods.proto +15 -15
  189. package/protos/webui/service_player.proto +918 -918
  190. package/protos/webui/service_promotioneventinvites.proto +109 -109
  191. package/protos/webui/service_promotionplanning.proto +186 -186
  192. package/protos/webui/service_promotionstats.proto +23 -23
  193. package/protos/webui/service_publishedfile.proto +714 -714
  194. package/protos/webui/service_publishing.proto +200 -200
  195. package/protos/webui/service_quest.proto +127 -127
  196. package/protos/webui/service_salefeature.proto +373 -373
  197. package/protos/webui/service_saleitemrewards.proto +54 -54
  198. package/protos/webui/service_shoppingcart.proto +152 -152
  199. package/protos/webui/service_steamawards.proto +76 -76
  200. package/protos/webui/service_steamcharts.proto +75 -75
  201. package/protos/webui/service_steamengine.proto +36 -36
  202. package/protos/webui/service_steamlearn.proto +876 -876
  203. package/protos/webui/service_steamnotification.proto +73 -73
  204. package/protos/webui/service_steamtv.proto +495 -495
  205. package/protos/webui/service_steamvrvoicechat.proto +67 -67
  206. package/protos/webui/service_steamvrwebrtc.proto +48 -48
  207. package/protos/webui/service_storagedevicemanager.proto +104 -104
  208. package/protos/webui/service_store.proto +359 -359
  209. package/protos/webui/service_storeappsimilarity.proto +76 -76
  210. package/protos/webui/service_storebrowse.proto +103 -103
  211. package/protos/webui/service_storemarketing.proto +44 -44
  212. package/protos/webui/service_storequery.proto +103 -103
  213. package/protos/webui/service_storesales.proto +87 -87
  214. package/protos/webui/service_storetopsellers.proto +44 -44
  215. package/protos/webui/service_systemmanager.proto +11 -11
  216. package/protos/webui/service_test_transporterror.proto +6 -6
  217. package/protos/webui/service_transportauth.proto +17 -17
  218. package/protos/webui/service_transportvalidation.proto +69 -69
  219. package/protos/webui/service_twofactor.proto +170 -170
  220. package/protos/webui/service_useraccount.proto +142 -142
  221. package/protos/webui/service_usergameactivity.proto +34 -34
  222. package/protos/webui/service_usergamenotes.proto +70 -70
  223. package/protos/webui/service_usernews.proto +68 -68
  224. package/protos/webui/service_userreviews.proto +97 -97
  225. package/protos/webui/service_video.proto +50 -50
  226. package/protos/webui/service_videoclip.proto +62 -62
  227. package/protos/webui/service_voicechat.proto +139 -139
  228. package/protos/webui/service_webrtc.proto +52 -52
  229. package/race.js +2241 -0
  230. package/remote.js +2249 -2249
  231. package/steamproto.js +146 -146
  232. package/utils.js +1219 -1150
  233. package/.idea/deployment.xml +0 -14
package/utils.js CHANGED
@@ -1,1150 +1,1219 @@
1
- import moment from "moment";
2
- import SteamTotp from "steam-totp";
3
- import { EAuthTokenPlatformType } from "./const.js";
4
- import fs from "fs";
5
- import axios from "axios";
6
- import readline from "readline";
7
- import https from "https";
8
- import { promisify } from "util";
9
- import { pipeline } from "stream";
10
- import _ from "lodash";
11
-
12
- const isBrowser = typeof window !== "undefined";
13
- const g_rgCurrencyData = {
14
- USD: {
15
- strCode: "USD",
16
- eCurrencyCode: 1,
17
- strSymbol: "$",
18
- bSymbolIsPrefix: true,
19
- bWholeUnitsOnly: false,
20
- strDecimalSymbol: ".",
21
- strThousandsSeparator: ",",
22
- strSymbolAndNumberSeparator: "",
23
- },
24
- GBP: {
25
- strCode: "GBP",
26
- eCurrencyCode: 2,
27
- strSymbol: "\u00a3",
28
- bSymbolIsPrefix: true,
29
- bWholeUnitsOnly: false,
30
- strDecimalSymbol: ".",
31
- strThousandsSeparator: ",",
32
- strSymbolAndNumberSeparator: "",
33
- },
34
- EUR: {
35
- strCode: "EUR",
36
- eCurrencyCode: 3,
37
- strSymbol: "\u20ac",
38
- bSymbolIsPrefix: false,
39
- bWholeUnitsOnly: false,
40
- strDecimalSymbol: ",",
41
- strThousandsSeparator: " ",
42
- strSymbolAndNumberSeparator: "",
43
- },
44
- CHF: {
45
- strCode: "CHF",
46
- eCurrencyCode: 4,
47
- strSymbol: "CHF",
48
- bSymbolIsPrefix: true,
49
- bWholeUnitsOnly: false,
50
- strDecimalSymbol: ".",
51
- strThousandsSeparator: " ",
52
- strSymbolAndNumberSeparator: " ",
53
- },
54
- RUB: {
55
- strCode: "RUB",
56
- eCurrencyCode: 5,
57
- strSymbol: "p\u0443\u0431.",
58
- bSymbolIsPrefix: false,
59
- bWholeUnitsOnly: true,
60
- strDecimalSymbol: ",",
61
- strThousandsSeparator: "",
62
- strSymbolAndNumberSeparator: " ",
63
- },
64
- BRL: {
65
- strCode: "BRL",
66
- eCurrencyCode: 7,
67
- strSymbol: "R$",
68
- bSymbolIsPrefix: true,
69
- bWholeUnitsOnly: false,
70
- strDecimalSymbol: ",",
71
- strThousandsSeparator: ".",
72
- strSymbolAndNumberSeparator: " ",
73
- },
74
- JPY: {
75
- strCode: "JPY",
76
- eCurrencyCode: 8,
77
- strSymbol: "\u00a5",
78
- bSymbolIsPrefix: true,
79
- bWholeUnitsOnly: true,
80
- strDecimalSymbol: ".",
81
- strThousandsSeparator: ",",
82
- strSymbolAndNumberSeparator: " ",
83
- },
84
- NOK: {
85
- strCode: "NOK",
86
- eCurrencyCode: 9,
87
- strSymbol: "kr",
88
- bSymbolIsPrefix: false,
89
- bWholeUnitsOnly: false,
90
- strDecimalSymbol: ",",
91
- strThousandsSeparator: ".",
92
- strSymbolAndNumberSeparator: " ",
93
- },
94
- IDR: {
95
- strCode: "IDR",
96
- eCurrencyCode: 10,
97
- strSymbol: "Rp",
98
- bSymbolIsPrefix: true,
99
- bWholeUnitsOnly: true,
100
- strDecimalSymbol: ".",
101
- strThousandsSeparator: " ",
102
- strSymbolAndNumberSeparator: " ",
103
- },
104
- MYR: {
105
- strCode: "MYR",
106
- eCurrencyCode: 11,
107
- strSymbol: "RM",
108
- bSymbolIsPrefix: true,
109
- bWholeUnitsOnly: false,
110
- strDecimalSymbol: ".",
111
- strThousandsSeparator: ",",
112
- strSymbolAndNumberSeparator: "",
113
- },
114
- PHP: {
115
- strCode: "PHP",
116
- eCurrencyCode: 12,
117
- strSymbol: "P",
118
- bSymbolIsPrefix: true,
119
- bWholeUnitsOnly: false,
120
- strDecimalSymbol: ".",
121
- strThousandsSeparator: ",",
122
- strSymbolAndNumberSeparator: "",
123
- },
124
- SGD: {
125
- strCode: "SGD",
126
- eCurrencyCode: 13,
127
- strSymbol: "S$",
128
- bSymbolIsPrefix: true,
129
- bWholeUnitsOnly: false,
130
- strDecimalSymbol: ".",
131
- strThousandsSeparator: ",",
132
- strSymbolAndNumberSeparator: "",
133
- },
134
- THB: {
135
- strCode: "THB",
136
- eCurrencyCode: 14,
137
- strSymbol: "\u0e3f",
138
- bSymbolIsPrefix: true,
139
- bWholeUnitsOnly: false,
140
- strDecimalSymbol: ".",
141
- strThousandsSeparator: ",",
142
- strSymbolAndNumberSeparator: "",
143
- },
144
- VND: {
145
- strCode: "VND",
146
- eCurrencyCode: 15,
147
- strSymbol: "\u20ab",
148
- bSymbolIsPrefix: false,
149
- bWholeUnitsOnly: true,
150
- strDecimalSymbol: ",",
151
- strThousandsSeparator: ".",
152
- strSymbolAndNumberSeparator: "",
153
- },
154
- KRW: {
155
- strCode: "KRW",
156
- eCurrencyCode: 16,
157
- strSymbol: "\u20a9",
158
- bSymbolIsPrefix: true,
159
- bWholeUnitsOnly: true,
160
- strDecimalSymbol: ".",
161
- strThousandsSeparator: ",",
162
- strSymbolAndNumberSeparator: " ",
163
- },
164
- TRY: {
165
- strCode: "TRY",
166
- eCurrencyCode: 17,
167
- strSymbol: "TL",
168
- bSymbolIsPrefix: false,
169
- bWholeUnitsOnly: false,
170
- strDecimalSymbol: ",",
171
- strThousandsSeparator: ".",
172
- strSymbolAndNumberSeparator: " ",
173
- },
174
- UAH: {
175
- strCode: "UAH",
176
- eCurrencyCode: 18,
177
- strSymbol: "\u20b4",
178
- bSymbolIsPrefix: false,
179
- bWholeUnitsOnly: true,
180
- strDecimalSymbol: ",",
181
- strThousandsSeparator: " ",
182
- strSymbolAndNumberSeparator: "",
183
- },
184
- MXN: {
185
- strCode: "MXN",
186
- eCurrencyCode: 19,
187
- strSymbol: "Mex$",
188
- bSymbolIsPrefix: true,
189
- bWholeUnitsOnly: false,
190
- strDecimalSymbol: ".",
191
- strThousandsSeparator: ",",
192
- strSymbolAndNumberSeparator: " ",
193
- },
194
- CAD: {
195
- strCode: "CAD",
196
- eCurrencyCode: 20,
197
- strSymbol: "CDN$",
198
- bSymbolIsPrefix: true,
199
- bWholeUnitsOnly: false,
200
- strDecimalSymbol: ".",
201
- strThousandsSeparator: ",",
202
- strSymbolAndNumberSeparator: " ",
203
- },
204
- AUD: {
205
- strCode: "AUD",
206
- eCurrencyCode: 21,
207
- strSymbol: "A$",
208
- bSymbolIsPrefix: true,
209
- bWholeUnitsOnly: false,
210
- strDecimalSymbol: ".",
211
- strThousandsSeparator: ",",
212
- strSymbolAndNumberSeparator: " ",
213
- },
214
- NZD: {
215
- strCode: "NZD",
216
- eCurrencyCode: 22,
217
- strSymbol: "NZ$",
218
- bSymbolIsPrefix: true,
219
- bWholeUnitsOnly: false,
220
- strDecimalSymbol: ".",
221
- strThousandsSeparator: ",",
222
- strSymbolAndNumberSeparator: " ",
223
- },
224
- PLN: {
225
- strCode: "PLN",
226
- eCurrencyCode: 6,
227
- strSymbol: "z\u0142",
228
- bSymbolIsPrefix: false,
229
- bWholeUnitsOnly: false,
230
- strDecimalSymbol: ",",
231
- strThousandsSeparator: " ",
232
- strSymbolAndNumberSeparator: "",
233
- },
234
- CNY: {
235
- strCode: "CNY",
236
- eCurrencyCode: 23,
237
- strSymbol: "\u00a5",
238
- bSymbolIsPrefix: true,
239
- bWholeUnitsOnly: false,
240
- strDecimalSymbol: ".",
241
- strThousandsSeparator: ",",
242
- strSymbolAndNumberSeparator: " ",
243
- },
244
- INR: {
245
- strCode: "INR",
246
- eCurrencyCode: 24,
247
- strSymbol: "\u20b9",
248
- bSymbolIsPrefix: true,
249
- bWholeUnitsOnly: true,
250
- strDecimalSymbol: ".",
251
- strThousandsSeparator: ",",
252
- strSymbolAndNumberSeparator: " ",
253
- },
254
- CLP: {
255
- strCode: "CLP",
256
- eCurrencyCode: 25,
257
- strSymbol: "CLP$",
258
- bSymbolIsPrefix: true,
259
- bWholeUnitsOnly: true,
260
- strDecimalSymbol: ",",
261
- strThousandsSeparator: ".",
262
- strSymbolAndNumberSeparator: " ",
263
- },
264
- PEN: {
265
- strCode: "PEN",
266
- eCurrencyCode: 26,
267
- strSymbol: "S/.",
268
- bSymbolIsPrefix: true,
269
- bWholeUnitsOnly: false,
270
- strDecimalSymbol: ".",
271
- strThousandsSeparator: ",",
272
- strSymbolAndNumberSeparator: "",
273
- },
274
- COP: {
275
- strCode: "COP",
276
- eCurrencyCode: 27,
277
- strSymbol: "COL$",
278
- bSymbolIsPrefix: true,
279
- bWholeUnitsOnly: true,
280
- strDecimalSymbol: ",",
281
- strThousandsSeparator: ".",
282
- strSymbolAndNumberSeparator: " ",
283
- },
284
- ZAR: {
285
- strCode: "ZAR",
286
- eCurrencyCode: 28,
287
- strSymbol: "R",
288
- bSymbolIsPrefix: true,
289
- bWholeUnitsOnly: false,
290
- strDecimalSymbol: ".",
291
- strThousandsSeparator: " ",
292
- strSymbolAndNumberSeparator: " ",
293
- },
294
- HKD: {
295
- strCode: "HKD",
296
- eCurrencyCode: 29,
297
- strSymbol: "HK$",
298
- bSymbolIsPrefix: true,
299
- bWholeUnitsOnly: false,
300
- strDecimalSymbol: ".",
301
- strThousandsSeparator: ",",
302
- strSymbolAndNumberSeparator: " ",
303
- },
304
- TWD: {
305
- strCode: "TWD",
306
- eCurrencyCode: 30,
307
- strSymbol: "NT$",
308
- bSymbolIsPrefix: true,
309
- bWholeUnitsOnly: true,
310
- strDecimalSymbol: ".",
311
- strThousandsSeparator: ",",
312
- strSymbolAndNumberSeparator: " ",
313
- },
314
- SAR: {
315
- strCode: "SAR",
316
- eCurrencyCode: 31,
317
- strSymbol: "SR",
318
- bSymbolIsPrefix: false,
319
- bWholeUnitsOnly: false,
320
- strDecimalSymbol: ".",
321
- strThousandsSeparator: ",",
322
- strSymbolAndNumberSeparator: " ",
323
- },
324
- AED: {
325
- strCode: "AED",
326
- eCurrencyCode: 32,
327
- strSymbol: "AED",
328
- bSymbolIsPrefix: false,
329
- bWholeUnitsOnly: false,
330
- strDecimalSymbol: ".",
331
- strThousandsSeparator: ",",
332
- strSymbolAndNumberSeparator: " ",
333
- },
334
- SEK: {
335
- strCode: "SEK",
336
- eCurrencyCode: 33,
337
- strSymbol: "kr",
338
- bSymbolIsPrefix: false,
339
- bWholeUnitsOnly: false,
340
- strDecimalSymbol: ".",
341
- strThousandsSeparator: ",",
342
- strSymbolAndNumberSeparator: " ",
343
- },
344
- ARS: {
345
- strCode: "ARS",
346
- eCurrencyCode: 34,
347
- strSymbol: "ARS$",
348
- bSymbolIsPrefix: true,
349
- bWholeUnitsOnly: false,
350
- strDecimalSymbol: ",",
351
- strThousandsSeparator: ".",
352
- strSymbolAndNumberSeparator: " ",
353
- },
354
- ILS: {
355
- strCode: "ILS",
356
- eCurrencyCode: 35,
357
- strSymbol: "\u20aa",
358
- bSymbolIsPrefix: true,
359
- bWholeUnitsOnly: false,
360
- strDecimalSymbol: ".",
361
- strThousandsSeparator: ",",
362
- strSymbolAndNumberSeparator: "",
363
- },
364
- BYN: {
365
- strCode: "BYN",
366
- eCurrencyCode: 36,
367
- strSymbol: "Br",
368
- bSymbolIsPrefix: true,
369
- bWholeUnitsOnly: false,
370
- strDecimalSymbol: ".",
371
- strThousandsSeparator: ",",
372
- strSymbolAndNumberSeparator: "",
373
- },
374
- KZT: {
375
- strCode: "KZT",
376
- eCurrencyCode: 37,
377
- strSymbol: "\u20b8",
378
- bSymbolIsPrefix: false,
379
- bWholeUnitsOnly: true,
380
- strDecimalSymbol: ",",
381
- strThousandsSeparator: " ",
382
- strSymbolAndNumberSeparator: "",
383
- },
384
- KWD: {
385
- strCode: "KWD",
386
- eCurrencyCode: 38,
387
- strSymbol: "KD",
388
- bSymbolIsPrefix: false,
389
- bWholeUnitsOnly: false,
390
- strDecimalSymbol: ".",
391
- strThousandsSeparator: ",",
392
- strSymbolAndNumberSeparator: " ",
393
- },
394
- QAR: {
395
- strCode: "QAR",
396
- eCurrencyCode: 39,
397
- strSymbol: "QR",
398
- bSymbolIsPrefix: false,
399
- bWholeUnitsOnly: false,
400
- strDecimalSymbol: ".",
401
- strThousandsSeparator: ",",
402
- strSymbolAndNumberSeparator: " ",
403
- },
404
- CRC: {
405
- strCode: "CRC",
406
- eCurrencyCode: 40,
407
- strSymbol: "\u20a1",
408
- bSymbolIsPrefix: true,
409
- bWholeUnitsOnly: true,
410
- strDecimalSymbol: ",",
411
- strThousandsSeparator: ".",
412
- strSymbolAndNumberSeparator: "",
413
- },
414
- UYU: {
415
- strCode: "UYU",
416
- eCurrencyCode: 41,
417
- strSymbol: "$U",
418
- bSymbolIsPrefix: true,
419
- bWholeUnitsOnly: true,
420
- strDecimalSymbol: ",",
421
- strThousandsSeparator: ".",
422
- strSymbolAndNumberSeparator: "",
423
- },
424
- BGN: {
425
- strCode: "BGN",
426
- eCurrencyCode: 42,
427
- strSymbol: "\u043b\u0432",
428
- bSymbolIsPrefix: false,
429
- bWholeUnitsOnly: false,
430
- strDecimalSymbol: ".",
431
- strThousandsSeparator: ",",
432
- strSymbolAndNumberSeparator: " ",
433
- },
434
- HRK: {
435
- strCode: "HRK",
436
- eCurrencyCode: 43,
437
- strSymbol: "kn",
438
- bSymbolIsPrefix: false,
439
- bWholeUnitsOnly: false,
440
- strDecimalSymbol: ".",
441
- strThousandsSeparator: ",",
442
- strSymbolAndNumberSeparator: " ",
443
- },
444
- CZK: {
445
- strCode: "CZK",
446
- eCurrencyCode: 44,
447
- strSymbol: "K\u010d",
448
- bSymbolIsPrefix: false,
449
- bWholeUnitsOnly: false,
450
- strDecimalSymbol: ".",
451
- strThousandsSeparator: ",",
452
- strSymbolAndNumberSeparator: " ",
453
- },
454
- DKK: {
455
- strCode: "DKK",
456
- eCurrencyCode: 45,
457
- strSymbol: "kr.",
458
- bSymbolIsPrefix: false,
459
- bWholeUnitsOnly: false,
460
- strDecimalSymbol: ".",
461
- strThousandsSeparator: ",",
462
- strSymbolAndNumberSeparator: " ",
463
- },
464
- HUF: {
465
- strCode: "HUF",
466
- eCurrencyCode: 46,
467
- strSymbol: "Ft",
468
- bSymbolIsPrefix: false,
469
- bWholeUnitsOnly: false,
470
- strDecimalSymbol: ".",
471
- strThousandsSeparator: ",",
472
- strSymbolAndNumberSeparator: " ",
473
- },
474
- RON: {
475
- strCode: "RON",
476
- eCurrencyCode: 47,
477
- strSymbol: "lei",
478
- bSymbolIsPrefix: false,
479
- bWholeUnitsOnly: false,
480
- strDecimalSymbol: ".",
481
- strThousandsSeparator: ",",
482
- strSymbolAndNumberSeparator: " ",
483
- },
484
- RMB: {
485
- strCode: "RMB",
486
- eCurrencyCode: 9000,
487
- strSymbol: "\u5200\u5e01",
488
- bSymbolIsPrefix: false,
489
- bWholeUnitsOnly: true,
490
- strDecimalSymbol: ".",
491
- strThousandsSeparator: "",
492
- strSymbolAndNumberSeparator: " ",
493
- },
494
- NXP: {
495
- strCode: "NXP",
496
- eCurrencyCode: 9001,
497
- strSymbol: "\uc6d0",
498
- bSymbolIsPrefix: false,
499
- bWholeUnitsOnly: true,
500
- strDecimalSymbol: ".",
501
- strThousandsSeparator: ",",
502
- strSymbolAndNumberSeparator: "",
503
- },
504
- };
505
- const g_rgWalletInfo = {
506
- wallet_currency: 15,
507
- wallet_country: "VN",
508
- wallet_state: "",
509
- wallet_fee: "1",
510
- wallet_fee_minimum: "1",
511
- wallet_fee_percent: "0.05",
512
- wallet_publisher_fee_percent_default: "0.10",
513
- wallet_fee_base: "0",
514
- wallet_balance: "6540490",
515
- wallet_delayed_balance: "0",
516
- wallet_max_balance: "4500000000",
517
- wallet_trade_max_balance: "4049999616",
518
- success: 1,
519
- rwgrsn: -2,
520
- };
521
-
522
- export const sleep = (ms) => {
523
- return new Promise((resolve) => {
524
- setTimeout(resolve, ms);
525
- });
526
- };
527
-
528
- export const sleepRandom = async (startMs, endMs) => {
529
- return await sleep(Math.random() * (endMs - startMs) + startMs);
530
- };
531
-
532
- /**
533
- * const audioTrack = stream.getAudioTracks()[0]
534
- * const videoStream = UserMedia.createBlankVideoTrack()
535
- * videoStream.addTrack(audioTrack)
536
- * stream = videoStream
537
- * **/
538
- export const createBlankVideoTrack = (opts = {}) => {
539
- const { width = 1920, height = 1080 } = opts;
540
-
541
- const canvas = Object.assign(document.createElement("canvas"), {
542
- width,
543
- height,
544
- });
545
-
546
- canvas.getContext("2d").fillRect(0, 0, width, height);
547
-
548
- return canvas.captureStream();
549
- };
550
-
551
- const minDate = new Date(0),
552
- maxDate = new Date(parseInt("ffffffff", 16) * 1000);
553
-
554
- export function objectIdFromDate(date) {
555
- if (date < minDate || date > maxDate) {
556
- return `Error: date must be between ${minDate.getFullYear()} and ${maxDate.getFullYear()}`;
557
- }
558
- var pad = "00000000";
559
- var hexSeconds = Math.floor(date.getTime() / 1000).toString(16);
560
- return `${pad.substring(0, pad.length - hexSeconds.length) + hexSeconds}0000000000000000`;
561
- }
562
-
563
- export function dateFromObjectId(objectId) {
564
- return new Date(parseInt(objectId.substring(0, 8), 16) * 1000);
565
- }
566
-
567
- export function console_log(...args) {
568
- const params = [];
569
- params.push(new Date().toUTCString());
570
- const errorStack = new Error().stack;
571
- const fnName = errorStack
572
- .split("\n")
573
- .map((e) => e?.trim())
574
- .filter((e) => e.startsWith("at") && !e.startsWith("at console_log") && !e.startsWith("at processTicksAndRejections"))[0]
575
- .substr(3);
576
- params.push(fnName);
577
- console.log(
578
- params
579
- .filter(Boolean)
580
- .map((p) => `[${p.trim()}]`)
581
- .join(" "),
582
- ...args,
583
- );
584
- }
585
-
586
- export function removeSpaceKeys(object) {
587
- //mutate object
588
- if (!object || Array.isArray(object)) {
589
- return object;
590
- }
591
-
592
- Object.entries(object).forEach(([key, value]) => {
593
- const newKey = key.replaceAll(/[^a-zA-Z0-9]/gi, "_");
594
- if (newKey !== key) {
595
- delete object[key];
596
- object[newKey] = value;
597
- }
598
- });
599
- return object;
600
- }
601
-
602
- export function getCleanObject(object) {
603
- //like removeSpaceKeys but not mutate object
604
- if (!object || Array.isArray(object)) {
605
- return object;
606
- }
607
-
608
- const newObject = {};
609
- Object.entries(object).forEach(([key, value]) => {
610
- const newKey = key.replaceAll(/[^a-zA-Z0-9]/gi, "_");
611
- newObject[newKey] = value;
612
- });
613
- return newObject;
614
- }
615
-
616
- export function JSON_parse(data) {
617
- try {
618
- return JSON.parse(data);
619
- } catch (e) {
620
- return null;
621
- }
622
- }
623
-
624
- export function JSON_stringify(data) {
625
- try {
626
- return JSON.stringify(data);
627
- } catch (e) {
628
- return null;
629
- }
630
- }
631
-
632
- export async function throttle(fn, delay) {
633
- let canFire = true;
634
- let queue = [];
635
-
636
- async function pop() {
637
- if (queue.length < 1) return;
638
-
639
- const [that, args] = queue.pop();
640
- await fn.apply(that, args);
641
- canFire = false;
642
- setTimeout(async () => {
643
- canFire = true;
644
- await pop();
645
- }, delay);
646
- }
647
-
648
- async function push() {
649
- queue.push([this, arguments]);
650
- if (canFire) {
651
- await pop();
652
- }
653
- }
654
-
655
- push.cancel = () => {
656
- queue = [];
657
- };
658
-
659
- return push;
660
- }
661
-
662
- export const secretAsBuffer = (sharedSecret) => {
663
- if (Buffer.isBuffer(sharedSecret)) {
664
- return sharedSecret;
665
- }
666
-
667
- if (sharedSecret.match(/^[0-9a-f]{40}$/i)) {
668
- // Looks like it's hex
669
- return Buffer.from(sharedSecret, "hex");
670
- }
671
-
672
- // It must be base64
673
- return Buffer.from(sharedSecret, "base64");
674
- };
675
-
676
- export function decodeLoginQrUrl(qrUrl) {
677
- if (!qrUrl || typeof qrUrl !== "string") {
678
- return null;
679
- }
680
- const match = qrUrl.match(/^https?:\/\/s\.team\/q\/(\d+)\/(\d+)(\?|$)/);
681
- if (!match) {
682
- console.log("Invalid QR code URL");
683
- return null;
684
- }
685
-
686
- return { clientId: match[2], version: parseInt(match[1], 10) };
687
- }
688
-
689
- export function decodeJwt(jwt) {
690
- try {
691
- const parts = jwt.split(".");
692
- if (parts.length !== 3) {
693
- console.err("decodeJwt Error", new Error("Invalid JWT"));
694
- return;
695
- }
696
-
697
- const standardBase64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
698
- return JSON.parse(Buffer.from(standardBase64, "base64").toString("utf8"));
699
- } catch (e) {
700
- console.error("decodeJwt Error", e);
701
- }
702
- }
703
-
704
- export async function renewRefreshToken({ refreshToken, accessToken }) {
705
- const steamId = arguments[0]?.steamId;
706
- try {
707
- const { aud } = decodeJwt(accessToken);
708
- let platformType = EAuthTokenPlatformType.SteamClient;
709
- if (aud.includes("mobile")) {
710
- platformType = EAuthTokenPlatformType.MobileApp;
711
- } else if (aud.includes("client")) {
712
- platformType = EAuthTokenPlatformType.SteamClient;
713
- } else if (aud.includes("web")) {
714
- platformType = EAuthTokenPlatformType.WebBrowser;
715
- }
716
-
717
- const { LoginSession } = await import("steam-session");
718
- const session = new LoginSession(platformType);
719
- session.refreshToken = refreshToken;
720
- await session.refreshAccessToken();
721
- const cookie = (await session.getWebCookies())?.join?.(";");
722
- return {
723
- cookie,
724
- accessToken: session.accessToken,
725
- accessTokenDecoded: decodeJwt(session.accessToken),
726
- };
727
- } catch (e) {
728
- console.error(`${steamId ? `[${steamId}] ` : ""}renewRefreshToken Error`, e);
729
- }
730
- }
731
-
732
- export async function approveLogin({ steamId, url, sharedSecret, accessToken, shouldApprove }) {
733
- try {
734
- const { LoginApprover } = await import("steam-session");
735
- const approver = new LoginApprover(accessToken, sharedSecret, {});
736
- const sessionInfo = await approver.getAuthSessionInfo(url);
737
- sessionInfo.steamId = steamId;
738
-
739
- if (typeof shouldApprove === "function" && !shouldApprove(sessionInfo)) {
740
- return;
741
- }
742
-
743
- await approver.approveAuthSession({
744
- qrChallengeUrl: url,
745
- approve: true,
746
- });
747
-
748
- return {
749
- steamId,
750
- sessionInfo,
751
- };
752
- } catch (error) {
753
- console.error(`[${steamId}] approveLogin Error`, error);
754
- return {
755
- steamId,
756
- error,
757
- };
758
- }
759
- }
760
-
761
- export function getBonusXpTimeRefresh() {
762
- let resetDay = moment.utc().startOf("isoWeek").add(2, "days").add(1, "hours");
763
- while (moment().isAfter(resetDay)) {
764
- resetDay = resetDay.add(7, "days");
765
- }
766
- if (moment().isBefore(resetDay)) {
767
- resetDay = resetDay.subtract(7, "days");
768
- }
769
- return resetDay;
770
- }
771
-
772
- export function estimateNextXp(currentXp, xpEarned) {
773
- //estimate next xp
774
- let bonusTime = 1;
775
- if (xpEarned < 4500) {
776
- bonusTime = 4;
777
- } else if (xpEarned < 7500) {
778
- bonusTime = 2;
779
- } else if (xpEarned < 11200) {
780
- bonusTime = 1;
781
- } else {
782
- bonusTime = 0.175;
783
- }
784
-
785
- const nextXp = 30 * 13 * bonusTime;
786
- return nextXp + currentXp;
787
- }
788
-
789
- export function formatMarketCurrency(valueInCents, currencyCode = getMarketCurrencyCode(g_rgWalletInfo.wallet_currency), countryCode) {
790
- if (!valueInCents && valueInCents !== 0) {
791
- return "";
792
- }
793
-
794
- let currencyFormat = (valueInCents / 100).toFixed(2);
795
-
796
- if (g_rgCurrencyData[currencyCode]) {
797
- const currencyData = g_rgCurrencyData[currencyCode];
798
- if (isCurrencyWholeUnits(currencyCode)) {
799
- currencyFormat = currencyFormat.replace(".00", "");
800
- }
801
-
802
- if (currencyData.strDecimalSymbol !== ".") {
803
- currencyFormat = currencyFormat.replace(".", currencyData.strDecimalSymbol);
804
- }
805
-
806
- const currencySymbol = getMarketCurrencySymbol(currencyCode);
807
- const currencyReturn = isCurrencySymbolBeforeValue(currencyCode) ? currencySymbol + currencyData.strSymbolAndNumberSeparator + currencyFormat : currencyFormat + currencyData.strSymbolAndNumberSeparator + currencySymbol;
808
-
809
- if (currencyCode === "USD" && typeof countryCode != "undefined" && countryCode != "US") {
810
- return `${currencyReturn} USD`;
811
- } else if (currencyCode === "EUR") {
812
- return currencyReturn.replace(",00", ",--");
813
- } else {
814
- return currencyReturn;
815
- }
816
- } else {
817
- return `${currencyFormat} ${currencyCode}`;
818
- }
819
- }
820
-
821
- export function getMarketPriceValueAsInt(strAmount) {
822
- let nAmount;
823
- if (!strAmount) {
824
- return 0;
825
- }
826
-
827
- // Users may enter either comma or period for the decimal mark and digit group separators.
828
- strAmount = strAmount.replace(/,/g, ".");
829
-
830
- // strip the currency symbol, set .-- to .00
831
- strAmount = strAmount.replace(getMarketCurrencySymbol(getMarketCurrencyCode(g_rgWalletInfo.wallet_currency)), "").replace(".--", ".00");
832
-
833
- // strip spaces
834
- strAmount = strAmount.replace(/ /g, "");
835
-
836
- // Remove all but the last period so that entries like "1,147.6" work
837
- if (strAmount.includes(".")) {
838
- var splitAmount = strAmount.split(".");
839
- var strLastSegment = splitAmount[splitAmount.length - 1];
840
-
841
- if (!isNaN(strLastSegment) && strLastSegment.length == 3 && splitAmount[splitAmount.length - 2] != "0") {
842
- // Looks like the user only entered thousands separators. Remove all commas and periods.
843
- // Ensures an entry like "1,147" is not treated as "1.147"
844
- //
845
- // Users may be surprised to find that "1.147" is treated as "1,147". "1.147" is either an error or the user
846
- // really did mean one thousand one hundred and forty seven since no currencies can be split into more than
847
- // hundredths. If it was an error, the user should notice in the next step of the dialog and can go back and
848
- // correct it. If they happen to not notice, it is better that we list the item at a higher price than
849
- // intended instead of lower than intended (which we would have done if we accepted the 1.147 value as is).
850
- strAmount = splitAmount.join("");
851
- } else {
852
- strAmount = `${splitAmount.slice(0, -1).join("")}.${strLastSegment}`;
853
- }
854
- }
855
-
856
- let flAmount = parseFloat(strAmount) * 100;
857
- nAmount = Math.floor(isNaN(flAmount) ? 0 : flAmount + 0.000001); // round down
858
-
859
- nAmount = Math.max(nAmount, 0);
860
- return nAmount;
861
- }
862
-
863
- export function isCurrencyWholeUnits(currencyCode) {
864
- return g_rgCurrencyData[currencyCode] && g_rgCurrencyData[currencyCode].bWholeUnitsOnly && currencyCode !== "RUB";
865
- }
866
-
867
- export function isCurrencySymbolBeforeValue(currencyCode) {
868
- return g_rgCurrencyData[currencyCode] && g_rgCurrencyData[currencyCode].bSymbolIsPrefix;
869
- }
870
-
871
- // Return the symbol to use for a currency
872
- export function getMarketCurrencySymbol(currencyCode) {
873
- return g_rgCurrencyData[currencyCode]?.strSymbol ?? currencyCode;
874
- }
875
-
876
- export function getMarketCurrencyCode(currencyId) {
877
- currencyId = parseInt(currencyId);
878
- for (const code in g_rgCurrencyData) {
879
- if (g_rgCurrencyData[code].eCurrencyCode === currencyId) {
880
- return code;
881
- }
882
- }
883
- return "Unknown";
884
- }
885
-
886
- export async function loginWithCredentials({ username, password, timeoutMs = 120000, sharedSecret, getMailSteamGuardCodes }) {
887
- if (!username) {
888
- return {
889
- error: "No username",
890
- };
891
- }
892
-
893
- if (!password) {
894
- return {
895
- error: "No password",
896
- };
897
- }
898
-
899
- const { LoginSession } = await import("steam-session");
900
- let authenticated = false;
901
- return new Promise((resolve) => {
902
- const timeout = setTimeout(function () {
903
- resolve({
904
- error: "Timed out",
905
- });
906
- }, timeoutMs);
907
-
908
- const session = new LoginSession(EAuthTokenPlatformType.MobileApp);
909
- session.on("authenticated", async () => {
910
- authenticated = true;
911
- const cookie = (await session.getWebCookies())?.join?.(";");
912
- return onResolve({
913
- cookie,
914
- accessToken: session.accessToken,
915
- refreshToken: session.refreshToken,
916
- accessTokenDecoded: decodeJwt(session.accessToken),
917
- });
918
- });
919
-
920
- session
921
- .startWithCredentials({
922
- accountName: username,
923
- password: password,
924
- steamGuardMachineToken: "",
925
- })
926
- .then(async function (startResult) {
927
- if (!startResult.actionRequired) {
928
- return;
929
- }
930
-
931
- if (sharedSecret) {
932
- let error = null;
933
- const maxRetry = 3;
934
- for (let i = 0; i < maxRetry; i++) {
935
- try {
936
- await session.submitSteamGuardCode(SteamTotp.generateAuthCode(sharedSecret));
937
- error = null;
938
- } catch (e) {
939
- error = e;
940
- }
941
- await sleep(1000);
942
- }
943
- if (error) {
944
- console.error(error);
945
- onResolve({ error });
946
- }
947
- } else {
948
- if (startResult.validActions.every((validAction) => validAction.type !== 2)) {
949
- console.error(startResult.validActions);
950
- return onResolve({
951
- error: "validActions",
952
- });
953
- }
954
-
955
- if (typeof getMailSteamGuardCodes === "function") {
956
- const codes = await getMailSteamGuardCodes();
957
- if (!Array.isArray(codes) || !codes.length) {
958
- return onResolve({
959
- error: "Can't find steam guard code",
960
- });
961
- }
962
-
963
- let error = null;
964
- for (const code of codes) {
965
- if (!authenticated) {
966
- try {
967
- await session.submitSteamGuardCode(code);
968
- error = null;
969
- } catch (e) {
970
- error = e;
971
- }
972
- await sleep(1000);
973
- }
974
- }
975
- if (!authenticated && error) {
976
- onResolve(error);
977
- }
978
- } else {
979
- return onResolve({
980
- error: "MailCodeError",
981
- });
982
- }
983
- }
984
- })
985
- .catch(function (e) {
986
- return onResolve(e);
987
- });
988
-
989
- function onResolve(data) {
990
- clearTimeout(timeout);
991
- return resolve(data);
992
- }
993
- });
994
- }
995
-
996
- export function calculateAccountXP(currentXp, xpEarnedThisWeek, xpEarned, nextXp) {
997
- return (
998
- (() => {
999
- if (typeof nextXp !== "number" || !Number.isFinite(nextXp)) {
1000
- return;
1001
- }
1002
-
1003
- currentXp = currentXp || 0;
1004
- if (currentXp === nextXp) {
1005
- return;
1006
- }
1007
-
1008
- const update = { currentXp: nextXp };
1009
- if (nextXp < currentXp) {
1010
- update.xpExceed = Date.now();
1011
- }
1012
- const resetDay = getBonusXpTimeRefresh().format("YYYY-MM-DD");
1013
- const isWeekReset = xpEarnedThisWeek !== resetDay;
1014
- let xpEarnedThisRank = nextXp - currentXp;
1015
- if (xpEarnedThisRank < 0) {
1016
- xpEarnedThisRank += 5000;
1017
- }
1018
- if (isWeekReset) {
1019
- update.xpEarnedThisWeek = resetDay;
1020
- update.xpEarned = xpEarnedThisRank;
1021
- } else {
1022
- update.xpEarned = (xpEarned || 0) + xpEarnedThisRank;
1023
- if (xpEarnedThisRank === 0) {
1024
- return;
1025
- }
1026
- }
1027
-
1028
- return update;
1029
- })() || {}
1030
- );
1031
- }
1032
-
1033
- export async function downloadImage(url, filePath) {
1034
- let response = null;
1035
- try {
1036
- response = await axios.get(url, {
1037
- responseType: "arraybuffer",
1038
- });
1039
- } catch (e) {
1040
- /* empty */
1041
- }
1042
-
1043
- if (!response || !response.data) {
1044
- return;
1045
- }
1046
-
1047
- return new Promise((resolve) => {
1048
- fs.writeFile(filePath, response.data, (err) => {
1049
- if (err) {
1050
- resolve();
1051
- }
1052
- resolve(filePath);
1053
- });
1054
- });
1055
- }
1056
-
1057
- export async function downloadLargeImage(url, filePath) {
1058
- try {
1059
- const response = await new Promise((resolve, reject) => {
1060
- https
1061
- .get(url, (res) => {
1062
- if (res.statusCode === 200) {
1063
- resolve(res);
1064
- } else {
1065
- reject(new Error(`Failed to get image, status code: ${res.statusCode}`));
1066
- }
1067
- })
1068
- .on("error", reject);
1069
- });
1070
-
1071
- const streamPipeline = promisify(pipeline);
1072
- await streamPipeline(response, fs.createWriteStream(filePath));
1073
- console.log("Download large image completed.");
1074
- return true;
1075
- } catch (error) {
1076
- console.error(`Error downloading large image: ${error.message}`);
1077
- return false;
1078
- }
1079
- }
1080
-
1081
- //from large text file
1082
- export function readRandomLine(filePath, isValidLine) {
1083
- return new Promise((resolve, reject) => {
1084
- const rl = readline.createInterface({
1085
- input: fs.createReadStream(filePath),
1086
- crlfDelay: Infinity,
1087
- });
1088
-
1089
- let resultLine = null;
1090
- let lineNumber = 0;
1091
-
1092
- rl.on("line", (line) => {
1093
- if (typeof isValidLine === "function" && !isValidLine(line)) {
1094
- return;
1095
- }
1096
-
1097
- lineNumber += 1;
1098
- // Choose this line with probability 1 / lineNumber
1099
- if (Math.random() < 1 / lineNumber) {
1100
- resultLine = line;
1101
- }
1102
- });
1103
-
1104
- rl.on("close", () => {
1105
- if (resultLine !== null) {
1106
- resolve(resultLine);
1107
- } else {
1108
- reject(new Error("File is empty"));
1109
- }
1110
- });
1111
-
1112
- rl.on("error", (err) => {
1113
- reject(err);
1114
- });
1115
- });
1116
- }
1117
-
1118
- export async function getImageSize(url) {
1119
- if (!url || typeof url !== "string") {
1120
- return;
1121
- }
1122
- let response = null;
1123
- try {
1124
- response = await axios.head(url);
1125
- } catch (e) {
1126
- /* empty */
1127
- }
1128
- if (!response) {
1129
- return;
1130
- }
1131
- const contentLength = response.headers?.["content-length"];
1132
- if (contentLength) {
1133
- const sizeInBytes = parseInt(contentLength, 10);
1134
- const sizeInMB = sizeInBytes / (1024 * 1024); // Convert to MB
1135
- return sizeInMB.toFixed(2); // Return size in MB with 2 decimal places
1136
- }
1137
- }
1138
-
1139
- export function getGreetMessage() {
1140
- return _.sample(["nha", "nhá", "nhé"]);
1141
- }
1142
-
1143
- export function logNow(...msg) {
1144
- const date = new Date();
1145
- const fmt = (n) => n.toString().padStart(2, "0");
1146
- const offset = 7 * 60;
1147
- const localDate = new Date(date.getTime() + offset * 60 * 1000);
1148
- const formattedDate = `${fmt(localDate.getUTCDate())}/${fmt(localDate.getUTCMonth() + 1)}/${localDate.getUTCFullYear()} ${fmt(localDate.getUTCHours())}:${fmt(localDate.getUTCMinutes())}:${fmt(localDate.getUTCSeconds())}`;
1149
- console.log(`[${formattedDate}]`, ...msg);
1150
- }
1
+ import moment from "moment";
2
+ import SteamTotp from "steam-totp";
3
+ import { EAuthTokenPlatformType } from "./const.js";
4
+ import fs from "fs";
5
+ import axios from "axios";
6
+ import readline from "readline";
7
+ import https from "https";
8
+ import { promisify } from "util";
9
+ import { pipeline } from "stream";
10
+ import _ from "lodash";
11
+
12
+ const isBrowser = typeof window !== "undefined";
13
+ const g_rgCurrencyData = {
14
+ USD: {
15
+ strCode: "USD",
16
+ eCurrencyCode: 1,
17
+ strSymbol: "$",
18
+ bSymbolIsPrefix: true,
19
+ bWholeUnitsOnly: false,
20
+ strDecimalSymbol: ".",
21
+ strThousandsSeparator: ",",
22
+ strSymbolAndNumberSeparator: "",
23
+ },
24
+ GBP: {
25
+ strCode: "GBP",
26
+ eCurrencyCode: 2,
27
+ strSymbol: "\u00a3",
28
+ bSymbolIsPrefix: true,
29
+ bWholeUnitsOnly: false,
30
+ strDecimalSymbol: ".",
31
+ strThousandsSeparator: ",",
32
+ strSymbolAndNumberSeparator: "",
33
+ },
34
+ EUR: {
35
+ strCode: "EUR",
36
+ eCurrencyCode: 3,
37
+ strSymbol: "\u20ac",
38
+ bSymbolIsPrefix: false,
39
+ bWholeUnitsOnly: false,
40
+ strDecimalSymbol: ",",
41
+ strThousandsSeparator: " ",
42
+ strSymbolAndNumberSeparator: "",
43
+ },
44
+ CHF: {
45
+ strCode: "CHF",
46
+ eCurrencyCode: 4,
47
+ strSymbol: "CHF",
48
+ bSymbolIsPrefix: true,
49
+ bWholeUnitsOnly: false,
50
+ strDecimalSymbol: ".",
51
+ strThousandsSeparator: " ",
52
+ strSymbolAndNumberSeparator: " ",
53
+ },
54
+ RUB: {
55
+ strCode: "RUB",
56
+ eCurrencyCode: 5,
57
+ strSymbol: "p\u0443\u0431.",
58
+ bSymbolIsPrefix: false,
59
+ bWholeUnitsOnly: true,
60
+ strDecimalSymbol: ",",
61
+ strThousandsSeparator: "",
62
+ strSymbolAndNumberSeparator: " ",
63
+ },
64
+ BRL: {
65
+ strCode: "BRL",
66
+ eCurrencyCode: 7,
67
+ strSymbol: "R$",
68
+ bSymbolIsPrefix: true,
69
+ bWholeUnitsOnly: false,
70
+ strDecimalSymbol: ",",
71
+ strThousandsSeparator: ".",
72
+ strSymbolAndNumberSeparator: " ",
73
+ },
74
+ JPY: {
75
+ strCode: "JPY",
76
+ eCurrencyCode: 8,
77
+ strSymbol: "\u00a5",
78
+ bSymbolIsPrefix: true,
79
+ bWholeUnitsOnly: true,
80
+ strDecimalSymbol: ".",
81
+ strThousandsSeparator: ",",
82
+ strSymbolAndNumberSeparator: " ",
83
+ },
84
+ NOK: {
85
+ strCode: "NOK",
86
+ eCurrencyCode: 9,
87
+ strSymbol: "kr",
88
+ bSymbolIsPrefix: false,
89
+ bWholeUnitsOnly: false,
90
+ strDecimalSymbol: ",",
91
+ strThousandsSeparator: ".",
92
+ strSymbolAndNumberSeparator: " ",
93
+ },
94
+ IDR: {
95
+ strCode: "IDR",
96
+ eCurrencyCode: 10,
97
+ strSymbol: "Rp",
98
+ bSymbolIsPrefix: true,
99
+ bWholeUnitsOnly: true,
100
+ strDecimalSymbol: ".",
101
+ strThousandsSeparator: " ",
102
+ strSymbolAndNumberSeparator: " ",
103
+ },
104
+ MYR: {
105
+ strCode: "MYR",
106
+ eCurrencyCode: 11,
107
+ strSymbol: "RM",
108
+ bSymbolIsPrefix: true,
109
+ bWholeUnitsOnly: false,
110
+ strDecimalSymbol: ".",
111
+ strThousandsSeparator: ",",
112
+ strSymbolAndNumberSeparator: "",
113
+ },
114
+ PHP: {
115
+ strCode: "PHP",
116
+ eCurrencyCode: 12,
117
+ strSymbol: "P",
118
+ bSymbolIsPrefix: true,
119
+ bWholeUnitsOnly: false,
120
+ strDecimalSymbol: ".",
121
+ strThousandsSeparator: ",",
122
+ strSymbolAndNumberSeparator: "",
123
+ },
124
+ SGD: {
125
+ strCode: "SGD",
126
+ eCurrencyCode: 13,
127
+ strSymbol: "S$",
128
+ bSymbolIsPrefix: true,
129
+ bWholeUnitsOnly: false,
130
+ strDecimalSymbol: ".",
131
+ strThousandsSeparator: ",",
132
+ strSymbolAndNumberSeparator: "",
133
+ },
134
+ THB: {
135
+ strCode: "THB",
136
+ eCurrencyCode: 14,
137
+ strSymbol: "\u0e3f",
138
+ bSymbolIsPrefix: true,
139
+ bWholeUnitsOnly: false,
140
+ strDecimalSymbol: ".",
141
+ strThousandsSeparator: ",",
142
+ strSymbolAndNumberSeparator: "",
143
+ },
144
+ VND: {
145
+ strCode: "VND",
146
+ eCurrencyCode: 15,
147
+ strSymbol: "\u20ab",
148
+ bSymbolIsPrefix: false,
149
+ bWholeUnitsOnly: true,
150
+ strDecimalSymbol: ",",
151
+ strThousandsSeparator: ".",
152
+ strSymbolAndNumberSeparator: "",
153
+ },
154
+ KRW: {
155
+ strCode: "KRW",
156
+ eCurrencyCode: 16,
157
+ strSymbol: "\u20a9",
158
+ bSymbolIsPrefix: true,
159
+ bWholeUnitsOnly: true,
160
+ strDecimalSymbol: ".",
161
+ strThousandsSeparator: ",",
162
+ strSymbolAndNumberSeparator: " ",
163
+ },
164
+ TRY: {
165
+ strCode: "TRY",
166
+ eCurrencyCode: 17,
167
+ strSymbol: "TL",
168
+ bSymbolIsPrefix: false,
169
+ bWholeUnitsOnly: false,
170
+ strDecimalSymbol: ",",
171
+ strThousandsSeparator: ".",
172
+ strSymbolAndNumberSeparator: " ",
173
+ },
174
+ UAH: {
175
+ strCode: "UAH",
176
+ eCurrencyCode: 18,
177
+ strSymbol: "\u20b4",
178
+ bSymbolIsPrefix: false,
179
+ bWholeUnitsOnly: true,
180
+ strDecimalSymbol: ",",
181
+ strThousandsSeparator: " ",
182
+ strSymbolAndNumberSeparator: "",
183
+ },
184
+ MXN: {
185
+ strCode: "MXN",
186
+ eCurrencyCode: 19,
187
+ strSymbol: "Mex$",
188
+ bSymbolIsPrefix: true,
189
+ bWholeUnitsOnly: false,
190
+ strDecimalSymbol: ".",
191
+ strThousandsSeparator: ",",
192
+ strSymbolAndNumberSeparator: " ",
193
+ },
194
+ CAD: {
195
+ strCode: "CAD",
196
+ eCurrencyCode: 20,
197
+ strSymbol: "CDN$",
198
+ bSymbolIsPrefix: true,
199
+ bWholeUnitsOnly: false,
200
+ strDecimalSymbol: ".",
201
+ strThousandsSeparator: ",",
202
+ strSymbolAndNumberSeparator: " ",
203
+ },
204
+ AUD: {
205
+ strCode: "AUD",
206
+ eCurrencyCode: 21,
207
+ strSymbol: "A$",
208
+ bSymbolIsPrefix: true,
209
+ bWholeUnitsOnly: false,
210
+ strDecimalSymbol: ".",
211
+ strThousandsSeparator: ",",
212
+ strSymbolAndNumberSeparator: " ",
213
+ },
214
+ NZD: {
215
+ strCode: "NZD",
216
+ eCurrencyCode: 22,
217
+ strSymbol: "NZ$",
218
+ bSymbolIsPrefix: true,
219
+ bWholeUnitsOnly: false,
220
+ strDecimalSymbol: ".",
221
+ strThousandsSeparator: ",",
222
+ strSymbolAndNumberSeparator: " ",
223
+ },
224
+ PLN: {
225
+ strCode: "PLN",
226
+ eCurrencyCode: 6,
227
+ strSymbol: "z\u0142",
228
+ bSymbolIsPrefix: false,
229
+ bWholeUnitsOnly: false,
230
+ strDecimalSymbol: ",",
231
+ strThousandsSeparator: " ",
232
+ strSymbolAndNumberSeparator: "",
233
+ },
234
+ CNY: {
235
+ strCode: "CNY",
236
+ eCurrencyCode: 23,
237
+ strSymbol: "\u00a5",
238
+ bSymbolIsPrefix: true,
239
+ bWholeUnitsOnly: false,
240
+ strDecimalSymbol: ".",
241
+ strThousandsSeparator: ",",
242
+ strSymbolAndNumberSeparator: " ",
243
+ },
244
+ INR: {
245
+ strCode: "INR",
246
+ eCurrencyCode: 24,
247
+ strSymbol: "\u20b9",
248
+ bSymbolIsPrefix: true,
249
+ bWholeUnitsOnly: true,
250
+ strDecimalSymbol: ".",
251
+ strThousandsSeparator: ",",
252
+ strSymbolAndNumberSeparator: " ",
253
+ },
254
+ CLP: {
255
+ strCode: "CLP",
256
+ eCurrencyCode: 25,
257
+ strSymbol: "CLP$",
258
+ bSymbolIsPrefix: true,
259
+ bWholeUnitsOnly: true,
260
+ strDecimalSymbol: ",",
261
+ strThousandsSeparator: ".",
262
+ strSymbolAndNumberSeparator: " ",
263
+ },
264
+ PEN: {
265
+ strCode: "PEN",
266
+ eCurrencyCode: 26,
267
+ strSymbol: "S/.",
268
+ bSymbolIsPrefix: true,
269
+ bWholeUnitsOnly: false,
270
+ strDecimalSymbol: ".",
271
+ strThousandsSeparator: ",",
272
+ strSymbolAndNumberSeparator: "",
273
+ },
274
+ COP: {
275
+ strCode: "COP",
276
+ eCurrencyCode: 27,
277
+ strSymbol: "COL$",
278
+ bSymbolIsPrefix: true,
279
+ bWholeUnitsOnly: true,
280
+ strDecimalSymbol: ",",
281
+ strThousandsSeparator: ".",
282
+ strSymbolAndNumberSeparator: " ",
283
+ },
284
+ ZAR: {
285
+ strCode: "ZAR",
286
+ eCurrencyCode: 28,
287
+ strSymbol: "R",
288
+ bSymbolIsPrefix: true,
289
+ bWholeUnitsOnly: false,
290
+ strDecimalSymbol: ".",
291
+ strThousandsSeparator: " ",
292
+ strSymbolAndNumberSeparator: " ",
293
+ },
294
+ HKD: {
295
+ strCode: "HKD",
296
+ eCurrencyCode: 29,
297
+ strSymbol: "HK$",
298
+ bSymbolIsPrefix: true,
299
+ bWholeUnitsOnly: false,
300
+ strDecimalSymbol: ".",
301
+ strThousandsSeparator: ",",
302
+ strSymbolAndNumberSeparator: " ",
303
+ },
304
+ TWD: {
305
+ strCode: "TWD",
306
+ eCurrencyCode: 30,
307
+ strSymbol: "NT$",
308
+ bSymbolIsPrefix: true,
309
+ bWholeUnitsOnly: true,
310
+ strDecimalSymbol: ".",
311
+ strThousandsSeparator: ",",
312
+ strSymbolAndNumberSeparator: " ",
313
+ },
314
+ SAR: {
315
+ strCode: "SAR",
316
+ eCurrencyCode: 31,
317
+ strSymbol: "SR",
318
+ bSymbolIsPrefix: false,
319
+ bWholeUnitsOnly: false,
320
+ strDecimalSymbol: ".",
321
+ strThousandsSeparator: ",",
322
+ strSymbolAndNumberSeparator: " ",
323
+ },
324
+ AED: {
325
+ strCode: "AED",
326
+ eCurrencyCode: 32,
327
+ strSymbol: "AED",
328
+ bSymbolIsPrefix: false,
329
+ bWholeUnitsOnly: false,
330
+ strDecimalSymbol: ".",
331
+ strThousandsSeparator: ",",
332
+ strSymbolAndNumberSeparator: " ",
333
+ },
334
+ SEK: {
335
+ strCode: "SEK",
336
+ eCurrencyCode: 33,
337
+ strSymbol: "kr",
338
+ bSymbolIsPrefix: false,
339
+ bWholeUnitsOnly: false,
340
+ strDecimalSymbol: ".",
341
+ strThousandsSeparator: ",",
342
+ strSymbolAndNumberSeparator: " ",
343
+ },
344
+ ARS: {
345
+ strCode: "ARS",
346
+ eCurrencyCode: 34,
347
+ strSymbol: "ARS$",
348
+ bSymbolIsPrefix: true,
349
+ bWholeUnitsOnly: false,
350
+ strDecimalSymbol: ",",
351
+ strThousandsSeparator: ".",
352
+ strSymbolAndNumberSeparator: " ",
353
+ },
354
+ ILS: {
355
+ strCode: "ILS",
356
+ eCurrencyCode: 35,
357
+ strSymbol: "\u20aa",
358
+ bSymbolIsPrefix: true,
359
+ bWholeUnitsOnly: false,
360
+ strDecimalSymbol: ".",
361
+ strThousandsSeparator: ",",
362
+ strSymbolAndNumberSeparator: "",
363
+ },
364
+ BYN: {
365
+ strCode: "BYN",
366
+ eCurrencyCode: 36,
367
+ strSymbol: "Br",
368
+ bSymbolIsPrefix: true,
369
+ bWholeUnitsOnly: false,
370
+ strDecimalSymbol: ".",
371
+ strThousandsSeparator: ",",
372
+ strSymbolAndNumberSeparator: "",
373
+ },
374
+ KZT: {
375
+ strCode: "KZT",
376
+ eCurrencyCode: 37,
377
+ strSymbol: "\u20b8",
378
+ bSymbolIsPrefix: false,
379
+ bWholeUnitsOnly: true,
380
+ strDecimalSymbol: ",",
381
+ strThousandsSeparator: " ",
382
+ strSymbolAndNumberSeparator: "",
383
+ },
384
+ KWD: {
385
+ strCode: "KWD",
386
+ eCurrencyCode: 38,
387
+ strSymbol: "KD",
388
+ bSymbolIsPrefix: false,
389
+ bWholeUnitsOnly: false,
390
+ strDecimalSymbol: ".",
391
+ strThousandsSeparator: ",",
392
+ strSymbolAndNumberSeparator: " ",
393
+ },
394
+ QAR: {
395
+ strCode: "QAR",
396
+ eCurrencyCode: 39,
397
+ strSymbol: "QR",
398
+ bSymbolIsPrefix: false,
399
+ bWholeUnitsOnly: false,
400
+ strDecimalSymbol: ".",
401
+ strThousandsSeparator: ",",
402
+ strSymbolAndNumberSeparator: " ",
403
+ },
404
+ CRC: {
405
+ strCode: "CRC",
406
+ eCurrencyCode: 40,
407
+ strSymbol: "\u20a1",
408
+ bSymbolIsPrefix: true,
409
+ bWholeUnitsOnly: true,
410
+ strDecimalSymbol: ",",
411
+ strThousandsSeparator: ".",
412
+ strSymbolAndNumberSeparator: "",
413
+ },
414
+ UYU: {
415
+ strCode: "UYU",
416
+ eCurrencyCode: 41,
417
+ strSymbol: "$U",
418
+ bSymbolIsPrefix: true,
419
+ bWholeUnitsOnly: true,
420
+ strDecimalSymbol: ",",
421
+ strThousandsSeparator: ".",
422
+ strSymbolAndNumberSeparator: "",
423
+ },
424
+ BGN: {
425
+ strCode: "BGN",
426
+ eCurrencyCode: 42,
427
+ strSymbol: "\u043b\u0432",
428
+ bSymbolIsPrefix: false,
429
+ bWholeUnitsOnly: false,
430
+ strDecimalSymbol: ".",
431
+ strThousandsSeparator: ",",
432
+ strSymbolAndNumberSeparator: " ",
433
+ },
434
+ HRK: {
435
+ strCode: "HRK",
436
+ eCurrencyCode: 43,
437
+ strSymbol: "kn",
438
+ bSymbolIsPrefix: false,
439
+ bWholeUnitsOnly: false,
440
+ strDecimalSymbol: ".",
441
+ strThousandsSeparator: ",",
442
+ strSymbolAndNumberSeparator: " ",
443
+ },
444
+ CZK: {
445
+ strCode: "CZK",
446
+ eCurrencyCode: 44,
447
+ strSymbol: "K\u010d",
448
+ bSymbolIsPrefix: false,
449
+ bWholeUnitsOnly: false,
450
+ strDecimalSymbol: ".",
451
+ strThousandsSeparator: ",",
452
+ strSymbolAndNumberSeparator: " ",
453
+ },
454
+ DKK: {
455
+ strCode: "DKK",
456
+ eCurrencyCode: 45,
457
+ strSymbol: "kr.",
458
+ bSymbolIsPrefix: false,
459
+ bWholeUnitsOnly: false,
460
+ strDecimalSymbol: ".",
461
+ strThousandsSeparator: ",",
462
+ strSymbolAndNumberSeparator: " ",
463
+ },
464
+ HUF: {
465
+ strCode: "HUF",
466
+ eCurrencyCode: 46,
467
+ strSymbol: "Ft",
468
+ bSymbolIsPrefix: false,
469
+ bWholeUnitsOnly: false,
470
+ strDecimalSymbol: ".",
471
+ strThousandsSeparator: ",",
472
+ strSymbolAndNumberSeparator: " ",
473
+ },
474
+ RON: {
475
+ strCode: "RON",
476
+ eCurrencyCode: 47,
477
+ strSymbol: "lei",
478
+ bSymbolIsPrefix: false,
479
+ bWholeUnitsOnly: false,
480
+ strDecimalSymbol: ".",
481
+ strThousandsSeparator: ",",
482
+ strSymbolAndNumberSeparator: " ",
483
+ },
484
+ RMB: {
485
+ strCode: "RMB",
486
+ eCurrencyCode: 9000,
487
+ strSymbol: "\u5200\u5e01",
488
+ bSymbolIsPrefix: false,
489
+ bWholeUnitsOnly: true,
490
+ strDecimalSymbol: ".",
491
+ strThousandsSeparator: "",
492
+ strSymbolAndNumberSeparator: " ",
493
+ },
494
+ NXP: {
495
+ strCode: "NXP",
496
+ eCurrencyCode: 9001,
497
+ strSymbol: "\uc6d0",
498
+ bSymbolIsPrefix: false,
499
+ bWholeUnitsOnly: true,
500
+ strDecimalSymbol: ".",
501
+ strThousandsSeparator: ",",
502
+ strSymbolAndNumberSeparator: "",
503
+ },
504
+ };
505
+ const g_rgWalletInfo = {
506
+ wallet_currency: 15,
507
+ wallet_country: "VN",
508
+ wallet_state: "",
509
+ wallet_fee: "1",
510
+ wallet_fee_minimum: "1",
511
+ wallet_fee_percent: "0.05",
512
+ wallet_publisher_fee_percent_default: "0.10",
513
+ wallet_fee_base: "0",
514
+ wallet_balance: "6540490",
515
+ wallet_delayed_balance: "0",
516
+ wallet_max_balance: "4500000000",
517
+ wallet_trade_max_balance: "4049999616",
518
+ success: 1,
519
+ rwgrsn: -2,
520
+ };
521
+
522
+ export const sleep = (ms) => {
523
+ return new Promise((resolve) => {
524
+ setTimeout(resolve, ms);
525
+ });
526
+ };
527
+
528
+ export const sleepRandom = async (startMs, endMs) => {
529
+ return await sleep(Math.random() * (endMs - startMs) + startMs);
530
+ };
531
+
532
+ /**
533
+ * const audioTrack = stream.getAudioTracks()[0]
534
+ * const videoStream = UserMedia.createBlankVideoTrack()
535
+ * videoStream.addTrack(audioTrack)
536
+ * stream = videoStream
537
+ * **/
538
+ export const createBlankVideoTrack = (opts = {}) => {
539
+ const { width = 1920, height = 1080 } = opts;
540
+
541
+ const canvas = Object.assign(document.createElement("canvas"), {
542
+ width,
543
+ height,
544
+ });
545
+
546
+ canvas.getContext("2d").fillRect(0, 0, width, height);
547
+
548
+ return canvas.captureStream();
549
+ };
550
+
551
+ const minDate = new Date(0),
552
+ maxDate = new Date(parseInt("ffffffff", 16) * 1000);
553
+
554
+ export function objectIdFromDate(date) {
555
+ if (date < minDate || date > maxDate) {
556
+ return `Error: date must be between ${minDate.getFullYear()} and ${maxDate.getFullYear()}`;
557
+ }
558
+ var pad = "00000000";
559
+ var hexSeconds = Math.floor(date.getTime() / 1000).toString(16);
560
+ return `${pad.substring(0, pad.length - hexSeconds.length) + hexSeconds}0000000000000000`;
561
+ }
562
+
563
+ export function dateFromObjectId(objectId) {
564
+ return new Date(parseInt(objectId.substring(0, 8), 16) * 1000);
565
+ }
566
+
567
+ export function console_log(...args) {
568
+ const params = [];
569
+ params.push(new Date().toUTCString());
570
+ const errorStack = new Error().stack;
571
+ const fnName = errorStack
572
+ .split("\n")
573
+ .map((e) => e?.trim())
574
+ .filter((e) => e.startsWith("at") && !e.startsWith("at console_log") && !e.startsWith("at processTicksAndRejections"))[0]
575
+ .substr(3);
576
+ params.push(fnName);
577
+ console.log(
578
+ params
579
+ .filter(Boolean)
580
+ .map((p) => `[${p.trim()}]`)
581
+ .join(" "),
582
+ ...args,
583
+ );
584
+ }
585
+
586
+ export function removeSpaceKeys(object) {
587
+ //mutate object
588
+ if (!object || Array.isArray(object)) {
589
+ return object;
590
+ }
591
+
592
+ Object.entries(object).forEach(([key, value]) => {
593
+ const newKey = key.replaceAll(/[^a-zA-Z0-9]/gi, "_");
594
+ if (newKey !== key) {
595
+ delete object[key];
596
+ object[newKey] = value;
597
+ }
598
+ });
599
+ return object;
600
+ }
601
+
602
+ export function getCleanObject(object) {
603
+ //like removeSpaceKeys but not mutate object
604
+ if (!object || Array.isArray(object)) {
605
+ return object;
606
+ }
607
+
608
+ const newObject = {};
609
+ Object.entries(object).forEach(([key, value]) => {
610
+ const newKey = key.replaceAll(/[^a-zA-Z0-9]/gi, "_");
611
+ newObject[newKey] = value;
612
+ });
613
+ return newObject;
614
+ }
615
+
616
+ export function JSON_parse(data) {
617
+ try {
618
+ return JSON.parse(data);
619
+ } catch (e) {
620
+ return null;
621
+ }
622
+ }
623
+
624
+ export function JSON_stringify(data) {
625
+ try {
626
+ return JSON.stringify(data);
627
+ } catch (e) {
628
+ return null;
629
+ }
630
+ }
631
+
632
+ export async function throttle(fn, delay) {
633
+ let canFire = true;
634
+ let queue = [];
635
+
636
+ async function pop() {
637
+ if (queue.length < 1) return;
638
+
639
+ const [that, args] = queue.pop();
640
+ await fn.apply(that, args);
641
+ canFire = false;
642
+ setTimeout(async () => {
643
+ canFire = true;
644
+ await pop();
645
+ }, delay);
646
+ }
647
+
648
+ async function push() {
649
+ queue.push([this, arguments]);
650
+ if (canFire) {
651
+ await pop();
652
+ }
653
+ }
654
+
655
+ push.cancel = () => {
656
+ queue = [];
657
+ };
658
+
659
+ return push;
660
+ }
661
+
662
+ export const secretAsBuffer = (sharedSecret) => {
663
+ if (Buffer.isBuffer(sharedSecret)) {
664
+ return sharedSecret;
665
+ }
666
+
667
+ if (sharedSecret.match(/^[0-9a-f]{40}$/i)) {
668
+ // Looks like it's hex
669
+ return Buffer.from(sharedSecret, "hex");
670
+ }
671
+
672
+ // It must be base64
673
+ return Buffer.from(sharedSecret, "base64");
674
+ };
675
+
676
+ export function decodeLoginQrUrl(qrUrl) {
677
+ if (!qrUrl || typeof qrUrl !== "string") {
678
+ return null;
679
+ }
680
+ const match = qrUrl.match(/^https?:\/\/s\.team\/q\/(\d+)\/(\d+)(\?|$)/);
681
+ if (!match) {
682
+ console.log("Invalid QR code URL");
683
+ return null;
684
+ }
685
+
686
+ return { clientId: match[2], version: parseInt(match[1], 10) };
687
+ }
688
+
689
+ export function decodeJwt(jwt) {
690
+ try {
691
+ const parts = jwt.split(".");
692
+ if (parts.length !== 3) {
693
+ console.err("decodeJwt Error", new Error("Invalid JWT"));
694
+ return;
695
+ }
696
+
697
+ const standardBase64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
698
+ return JSON.parse(Buffer.from(standardBase64, "base64").toString("utf8"));
699
+ } catch (e) {
700
+ console.error("decodeJwt Error", e);
701
+ }
702
+ }
703
+
704
+ export async function renewRefreshToken({ refreshToken, accessToken }) {
705
+ const steamId = arguments[0]?.steamId;
706
+ try {
707
+ const { aud } = decodeJwt(accessToken);
708
+ let platformType = EAuthTokenPlatformType.SteamClient;
709
+ if (aud.includes("mobile")) {
710
+ platformType = EAuthTokenPlatformType.MobileApp;
711
+ } else if (aud.includes("client")) {
712
+ platformType = EAuthTokenPlatformType.SteamClient;
713
+ } else if (aud.includes("web")) {
714
+ platformType = EAuthTokenPlatformType.WebBrowser;
715
+ }
716
+
717
+ const { LoginSession } = await import("steam-session");
718
+ const session = new LoginSession(platformType);
719
+ session.refreshToken = refreshToken;
720
+ await session.refreshAccessToken();
721
+ const cookie = (await session.getWebCookies())?.join?.(";");
722
+ return {
723
+ cookie,
724
+ accessToken: session.accessToken,
725
+ accessTokenDecoded: decodeJwt(session.accessToken),
726
+ };
727
+ } catch (e) {
728
+ console.error(`${steamId ? `[${steamId}] ` : ""}renewRefreshToken Error`, e);
729
+ }
730
+ }
731
+
732
+ export async function approveLogin({ steamId, url, sharedSecret, accessToken, shouldApprove }) {
733
+ try {
734
+ const { LoginApprover } = await import("steam-session");
735
+ const approver = new LoginApprover(accessToken, sharedSecret, {});
736
+ const sessionInfo = await approver.getAuthSessionInfo(url);
737
+ sessionInfo.steamId = steamId;
738
+
739
+ if (typeof shouldApprove === "function" && !shouldApprove(sessionInfo)) {
740
+ return;
741
+ }
742
+
743
+ await approver.approveAuthSession({
744
+ qrChallengeUrl: url,
745
+ approve: true,
746
+ });
747
+
748
+ return {
749
+ steamId,
750
+ sessionInfo,
751
+ };
752
+ } catch (error) {
753
+ console.error(`[${steamId}] approveLogin Error`, error);
754
+ return {
755
+ steamId,
756
+ error,
757
+ };
758
+ }
759
+ }
760
+
761
+ export function getBonusXpTimeRefresh() {
762
+ let resetDay = moment.utc().startOf("isoWeek").add(2, "days").add(1, "hours");
763
+ while (moment().isAfter(resetDay)) {
764
+ resetDay = resetDay.add(7, "days");
765
+ }
766
+ if (moment().isBefore(resetDay)) {
767
+ resetDay = resetDay.subtract(7, "days");
768
+ }
769
+ return resetDay;
770
+ }
771
+
772
+ export function estimateNextXp(currentXp, xpEarned) {
773
+ //estimate next xp
774
+ let bonusTime = 1;
775
+ if (xpEarned < 4500) {
776
+ bonusTime = 4;
777
+ } else if (xpEarned < 7500) {
778
+ bonusTime = 2;
779
+ } else if (xpEarned < 11200) {
780
+ bonusTime = 1;
781
+ } else {
782
+ bonusTime = 0.175;
783
+ }
784
+
785
+ const nextXp = 30 * 13 * bonusTime;
786
+ return nextXp + currentXp;
787
+ }
788
+
789
+ export function formatMarketCurrency(valueInCents, currencyCode = getMarketCurrencyCode(g_rgWalletInfo.wallet_currency), countryCode) {
790
+ if (!valueInCents && valueInCents !== 0) {
791
+ return "";
792
+ }
793
+
794
+ let currencyFormat = (valueInCents / 100).toFixed(2);
795
+
796
+ if (g_rgCurrencyData[currencyCode]) {
797
+ const currencyData = g_rgCurrencyData[currencyCode];
798
+ if (isCurrencyWholeUnits(currencyCode)) {
799
+ currencyFormat = currencyFormat.replace(".00", "");
800
+ }
801
+
802
+ if (currencyData.strDecimalSymbol !== ".") {
803
+ currencyFormat = currencyFormat.replace(".", currencyData.strDecimalSymbol);
804
+ }
805
+
806
+ const currencySymbol = getMarketCurrencySymbol(currencyCode);
807
+ const currencyReturn = isCurrencySymbolBeforeValue(currencyCode) ? currencySymbol + currencyData.strSymbolAndNumberSeparator + currencyFormat : currencyFormat + currencyData.strSymbolAndNumberSeparator + currencySymbol;
808
+
809
+ if (currencyCode === "USD" && typeof countryCode != "undefined" && countryCode != "US") {
810
+ return `${currencyReturn} USD`;
811
+ } else if (currencyCode === "EUR") {
812
+ return currencyReturn.replace(",00", ",--");
813
+ } else {
814
+ return currencyReturn;
815
+ }
816
+ } else {
817
+ return `${currencyFormat} ${currencyCode}`;
818
+ }
819
+ }
820
+
821
+ export function getMarketPriceValueAsInt(strAmount) {
822
+ let nAmount;
823
+ if (!strAmount) {
824
+ return 0;
825
+ }
826
+
827
+ // Users may enter either comma or period for the decimal mark and digit group separators.
828
+ strAmount = strAmount.replace(/,/g, ".");
829
+
830
+ // strip the currency symbol, set .-- to .00
831
+ strAmount = strAmount.replace(getMarketCurrencySymbol(getMarketCurrencyCode(g_rgWalletInfo.wallet_currency)), "").replace(".--", ".00");
832
+
833
+ // strip spaces
834
+ strAmount = strAmount.replace(/ /g, "");
835
+
836
+ // Remove all but the last period so that entries like "1,147.6" work
837
+ if (strAmount.includes(".")) {
838
+ var splitAmount = strAmount.split(".");
839
+ var strLastSegment = splitAmount[splitAmount.length - 1];
840
+
841
+ if (!isNaN(strLastSegment) && strLastSegment.length == 3 && splitAmount[splitAmount.length - 2] != "0") {
842
+ // Looks like the user only entered thousands separators. Remove all commas and periods.
843
+ // Ensures an entry like "1,147" is not treated as "1.147"
844
+ //
845
+ // Users may be surprised to find that "1.147" is treated as "1,147". "1.147" is either an error or the user
846
+ // really did mean one thousand one hundred and forty seven since no currencies can be split into more than
847
+ // hundredths. If it was an error, the user should notice in the next step of the dialog and can go back and
848
+ // correct it. If they happen to not notice, it is better that we list the item at a higher price than
849
+ // intended instead of lower than intended (which we would have done if we accepted the 1.147 value as is).
850
+ strAmount = splitAmount.join("");
851
+ } else {
852
+ strAmount = `${splitAmount.slice(0, -1).join("")}.${strLastSegment}`;
853
+ }
854
+ }
855
+
856
+ let flAmount = parseFloat(strAmount) * 100;
857
+ nAmount = Math.floor(isNaN(flAmount) ? 0 : flAmount + 0.000001); // round down
858
+
859
+ nAmount = Math.max(nAmount, 0);
860
+ return nAmount;
861
+ }
862
+
863
+ export function isCurrencyWholeUnits(currencyCode) {
864
+ return g_rgCurrencyData[currencyCode] && g_rgCurrencyData[currencyCode].bWholeUnitsOnly && currencyCode !== "RUB";
865
+ }
866
+
867
+ export function isCurrencySymbolBeforeValue(currencyCode) {
868
+ return g_rgCurrencyData[currencyCode] && g_rgCurrencyData[currencyCode].bSymbolIsPrefix;
869
+ }
870
+
871
+ // Return the symbol to use for a currency
872
+ export function getMarketCurrencySymbol(currencyCode) {
873
+ return g_rgCurrencyData[currencyCode]?.strSymbol ?? currencyCode;
874
+ }
875
+
876
+ export function getMarketCurrencyCode(currencyId) {
877
+ currencyId = parseInt(currencyId);
878
+ for (const code in g_rgCurrencyData) {
879
+ if (g_rgCurrencyData[code].eCurrencyCode === currencyId) {
880
+ return code;
881
+ }
882
+ }
883
+ return "Unknown";
884
+ }
885
+
886
+ export async function loginWithCredentials({ username, password, timeoutMs = 120000, sharedSecret, getMailSteamGuardCodes }) {
887
+ if (!username) {
888
+ return {
889
+ error: "No username",
890
+ };
891
+ }
892
+
893
+ if (!password) {
894
+ return {
895
+ error: "No password",
896
+ };
897
+ }
898
+
899
+ const { LoginSession } = await import("steam-session");
900
+ let authenticated = false;
901
+ return new Promise((resolve) => {
902
+ const timeout = setTimeout(function () {
903
+ resolve({
904
+ error: "Timed out",
905
+ });
906
+ }, timeoutMs);
907
+
908
+ const session = new LoginSession(EAuthTokenPlatformType.MobileApp);
909
+ session.on("authenticated", async () => {
910
+ authenticated = true;
911
+ const cookie = (await session.getWebCookies())?.join?.(";");
912
+ return onResolve({
913
+ cookie,
914
+ accessToken: session.accessToken,
915
+ refreshToken: session.refreshToken,
916
+ accessTokenDecoded: decodeJwt(session.accessToken),
917
+ });
918
+ });
919
+
920
+ session
921
+ .startWithCredentials({
922
+ accountName: username,
923
+ password: password,
924
+ steamGuardMachineToken: "",
925
+ })
926
+ .then(async function (startResult) {
927
+ if (!startResult.actionRequired) {
928
+ return;
929
+ }
930
+
931
+ if (sharedSecret) {
932
+ let error = null;
933
+ const maxRetry = 3;
934
+ for (let i = 0; i < maxRetry; i++) {
935
+ try {
936
+ await session.submitSteamGuardCode(SteamTotp.generateAuthCode(sharedSecret));
937
+ error = null;
938
+ } catch (e) {
939
+ error = e;
940
+ }
941
+ await sleep(1000);
942
+ }
943
+ if (error) {
944
+ console.error(error);
945
+ onResolve({ error });
946
+ }
947
+ } else {
948
+ if (startResult.validActions.every((validAction) => validAction.type !== 2)) {
949
+ console.error(startResult.validActions);
950
+ return onResolve({
951
+ error: "validActions",
952
+ });
953
+ }
954
+
955
+ if (typeof getMailSteamGuardCodes === "function") {
956
+ const codes = await getMailSteamGuardCodes();
957
+ if (!Array.isArray(codes) || !codes.length) {
958
+ return onResolve({
959
+ error: "Can't find steam guard code",
960
+ });
961
+ }
962
+
963
+ let error = null;
964
+ for (const code of codes) {
965
+ if (!authenticated) {
966
+ try {
967
+ await session.submitSteamGuardCode(code);
968
+ error = null;
969
+ } catch (e) {
970
+ error = e;
971
+ }
972
+ await sleep(1000);
973
+ }
974
+ }
975
+ if (!authenticated && error) {
976
+ onResolve(error);
977
+ }
978
+ } else {
979
+ return onResolve({
980
+ error: "MailCodeError",
981
+ });
982
+ }
983
+ }
984
+ })
985
+ .catch(function (e) {
986
+ return onResolve(e);
987
+ });
988
+
989
+ function onResolve(data) {
990
+ clearTimeout(timeout);
991
+ return resolve(data);
992
+ }
993
+ });
994
+ }
995
+
996
+ export function calculateAccountXP(currentXp, xpEarnedThisWeek, xpEarned, nextXp) {
997
+ return (
998
+ (() => {
999
+ if (typeof nextXp !== "number" || !Number.isFinite(nextXp)) {
1000
+ return;
1001
+ }
1002
+
1003
+ currentXp = currentXp || 0;
1004
+ if (currentXp === nextXp) {
1005
+ return;
1006
+ }
1007
+
1008
+ const update = { currentXp: nextXp };
1009
+ if (nextXp < currentXp) {
1010
+ update.xpExceed = Date.now();
1011
+ }
1012
+ const resetDay = getBonusXpTimeRefresh().format("YYYY-MM-DD");
1013
+ const isWeekReset = xpEarnedThisWeek !== resetDay;
1014
+ let xpEarnedThisRank = nextXp - currentXp;
1015
+ if (xpEarnedThisRank < 0) {
1016
+ xpEarnedThisRank += 5000;
1017
+ }
1018
+ if (isWeekReset) {
1019
+ update.xpEarnedThisWeek = resetDay;
1020
+ update.xpEarned = xpEarnedThisRank;
1021
+ } else {
1022
+ update.xpEarned = (xpEarned || 0) + xpEarnedThisRank;
1023
+ if (xpEarnedThisRank === 0) {
1024
+ return;
1025
+ }
1026
+ }
1027
+
1028
+ return update;
1029
+ })() || {}
1030
+ );
1031
+ }
1032
+
1033
+ export async function downloadImage(url, filePath) {
1034
+ let response = null;
1035
+ try {
1036
+ response = await axios.get(url, {
1037
+ responseType: "arraybuffer",
1038
+ });
1039
+ } catch (e) {
1040
+ /* empty */
1041
+ }
1042
+
1043
+ if (!response || !response.data) {
1044
+ return;
1045
+ }
1046
+
1047
+ return new Promise((resolve) => {
1048
+ fs.writeFile(filePath, response.data, (err) => {
1049
+ if (err) {
1050
+ resolve();
1051
+ }
1052
+ resolve(filePath);
1053
+ });
1054
+ });
1055
+ }
1056
+
1057
+ export async function downloadLargeImage(url, filePath) {
1058
+ try {
1059
+ const response = await new Promise((resolve, reject) => {
1060
+ https
1061
+ .get(url, (res) => {
1062
+ if (res.statusCode === 200) {
1063
+ resolve(res);
1064
+ } else {
1065
+ reject(new Error(`Failed to get image, status code: ${res.statusCode}`));
1066
+ }
1067
+ })
1068
+ .on("error", reject);
1069
+ });
1070
+
1071
+ const streamPipeline = promisify(pipeline);
1072
+ await streamPipeline(response, fs.createWriteStream(filePath));
1073
+ console.log("Download large image completed.");
1074
+ return true;
1075
+ } catch (error) {
1076
+ console.error(`Error downloading large image: ${error.message}`);
1077
+ return false;
1078
+ }
1079
+ }
1080
+
1081
+ //from large text file
1082
+ export function readRandomLine(filePath, isValidLine) {
1083
+ return new Promise((resolve, reject) => {
1084
+ const rl = readline.createInterface({
1085
+ input: fs.createReadStream(filePath),
1086
+ crlfDelay: Infinity,
1087
+ });
1088
+
1089
+ let resultLine = null;
1090
+ let lineNumber = 0;
1091
+
1092
+ rl.on("line", (line) => {
1093
+ if (typeof isValidLine === "function" && !isValidLine(line)) {
1094
+ return;
1095
+ }
1096
+
1097
+ lineNumber += 1;
1098
+ // Choose this line with probability 1 / lineNumber
1099
+ if (Math.random() < 1 / lineNumber) {
1100
+ resultLine = line;
1101
+ }
1102
+ });
1103
+
1104
+ rl.on("close", () => {
1105
+ if (resultLine !== null) {
1106
+ resolve(resultLine);
1107
+ } else {
1108
+ reject(new Error("File is empty"));
1109
+ }
1110
+ });
1111
+
1112
+ rl.on("error", (err) => {
1113
+ reject(err);
1114
+ });
1115
+ });
1116
+ }
1117
+
1118
+ export async function getImageSize(url) {
1119
+ if (!url || typeof url !== "string") {
1120
+ return;
1121
+ }
1122
+ let response = null;
1123
+ try {
1124
+ response = await axios.head(url);
1125
+ } catch (e) {
1126
+ /* empty */
1127
+ }
1128
+ if (!response) {
1129
+ return;
1130
+ }
1131
+ const contentLength = response.headers?.["content-length"];
1132
+ if (contentLength) {
1133
+ const sizeInBytes = parseInt(contentLength, 10);
1134
+ const sizeInMB = sizeInBytes / (1024 * 1024); // Convert to MB
1135
+ return sizeInMB.toFixed(2); // Return size in MB with 2 decimal places
1136
+ }
1137
+ }
1138
+
1139
+ export function getGreetMessage() {
1140
+ return _.sample(["nha", "nhá", "nhé"]);
1141
+ }
1142
+
1143
+ export function logNow(...msg) {
1144
+ const date = new Date();
1145
+ const fmt = (n) => n.toString().padStart(2, "0");
1146
+ const offset = 7 * 60;
1147
+ const localDate = new Date(date.getTime() + offset * 60 * 1000);
1148
+ const formattedDate = `${fmt(localDate.getUTCDate())}/${fmt(localDate.getUTCMonth() + 1)}/${localDate.getUTCFullYear()} ${fmt(localDate.getUTCHours())}:${fmt(localDate.getUTCMinutes())}:${fmt(localDate.getUTCSeconds())}`;
1149
+ console.log(`[${formattedDate}]`, ...msg);
1150
+ }
1151
+
1152
+ export function formatFriendState(data) {
1153
+ if (!data) {
1154
+ return;
1155
+ }
1156
+
1157
+ function formatUndefined(value) {
1158
+ if (value === "" || value === null || value === undefined || (typeof value === "number" && isNaN(value))) {
1159
+ return null;
1160
+ }
1161
+ return value;
1162
+ }
1163
+
1164
+ const { player_name, gameid, persona_state, rich_presence = [] } = data;
1165
+ const avatar_hash = data.avatar_hash ? (typeof data.avatar_hash === "string" ? data.avatar_hash : Buffer.from(data.avatar_hash).toString("hex")) : "fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb";
1166
+
1167
+ let onlineStatus = "offline";
1168
+ let score = "";
1169
+ const scoreDetails = rich_presence.find((r) => r.key === "game:score")?.value;
1170
+ const mode = rich_presence.find((r) => r.key === "game:mode")?.value;
1171
+ const map = rich_presence.find((r) => r.key === "game:map")?.value;
1172
+ const numPlayers = formatUndefined(parseInt(rich_presence.find((r) => r.key === "members:numPlayers")?.value)); //include this friend, 2,3,4,5
1173
+ const steam_player_group = formatUndefined(parseInt(rich_presence.find?.((r) => r.key === "steam_player_group")?.value));
1174
+ const steam_player_group_size = formatUndefined(parseInt(rich_presence.find?.((r) => r.key === "steam_player_group_size")?.value));
1175
+
1176
+ if (gameid !== null && gameid !== undefined && gameid !== "") {
1177
+ if (gameid === 0 || gameid === "0") {
1178
+ if ([1, 2, 3, 4].includes(persona_state)) {
1179
+ onlineStatus = "online";
1180
+ } else if (persona_state === 0) {
1181
+ onlineStatus = "offline";
1182
+ } else {
1183
+ // console.log(data)
1184
+ onlineStatus = "online";
1185
+ }
1186
+ } else {
1187
+ onlineStatus = "ingame";
1188
+ }
1189
+
1190
+ if (rich_presence.some((r) => r.key === "game:state" && r.value === "lobby")) {
1191
+ score = data.rich_presence_string || "In Lobby";
1192
+ } else {
1193
+ score = rich_presence.find?.((r) => r.key === "status")?.value || data.rich_presence_string || "";
1194
+ }
1195
+ if (score === "not found") {
1196
+ score = "";
1197
+ }
1198
+ if (score.startsWith("Premier") && !score.startsWith("Premier Competitive") && data.rich_presence_string?.startsWith("Premier Competitive")) {
1199
+ score = data.rich_presence_string;
1200
+ }
1201
+ } else if (persona_state === null && rich_presence.length === 0) {
1202
+ onlineStatus = "offline";
1203
+ }
1204
+
1205
+ return {
1206
+ onlineStatus,
1207
+ score: formatUndefined(score),
1208
+ scoreDetails: formatUndefined(scoreDetails),
1209
+ mode: formatUndefined(mode),
1210
+ map: formatUndefined(map),
1211
+ player_name,
1212
+ gameid: formatUndefined(parseInt(gameid)),
1213
+ numPlayers,
1214
+ steam_player_group,
1215
+ steam_player_group_size,
1216
+ avatar_hash,
1217
+ rich_presence,
1218
+ };
1219
+ }