@lzpenguin/server 1.1.0 → 1.1.1

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 (4) hide show
  1. package/README.md +14 -15
  2. package/index.d.ts +2 -6
  3. package/index.js +29 -18
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -13,10 +13,11 @@ npm install @lzpenguin/server
13
13
  ```javascript
14
14
  import { RiffleServer } from '@lzpenguin/server';
15
15
 
16
+ // post_id 和 token 会自动从浏览器 URL 参数中读取
17
+ // 例如:https://example.com/game.html?post_id=123456&token=your-token-here
16
18
  const server = new RiffleServer({
17
19
  url: 'wss://api.riffle.app',
18
- postId: 123456,
19
- token: 'your-token-here'
20
+ timestamp: 'timestamp given in the context' // 游戏时间戳,用于判断是否需要重新初始化
20
21
  });
21
22
 
22
23
  // 监听数据更新
@@ -28,7 +29,6 @@ server.onData((data) => {
28
29
 
29
30
  // 初始化服务器
30
31
  server.init({
31
- hash: 'game-version-hash-123',
32
32
  world: { score: 0, level: 1 },
33
33
  self: {
34
34
  public: { name: 'Player1', x: 100, y: 100 }
@@ -42,23 +42,23 @@ server.init({
42
42
 
43
43
  ```javascript
44
44
  new RiffleServer({
45
- url: 'wss://api.riffle.app', // 必需:WebSocket 服务器 URL
46
- postId: 123456, // 必需:游戏贴文 ID
47
- token: 'your-token-here', // 必需:认证 token
45
+ url: 'wss://api.riffle.app', // 必需:WebSocket 服务器 URL
46
+ timestamp: 'timestamp given in the context', // 必需:游戏时间戳(用于判断是否需要重新初始化,新 timestamp 必须大于旧的才会重置)
48
47
  autoReconnect: true, // 可选:是否自动重连,默认 true
49
48
  reconnectInterval: 3000 // 可选:重连间隔(毫秒),默认 3000
50
49
  })
50
+ // 注意:post_id 和 token 会自动从浏览器 URL 参数中读取
51
+ // 页面 URL 格式:https://example.com/game.html?post_id=123456&token=your-token-here
51
52
  ```
52
53
 
53
54
  ## 三种消息类型
54
55
 
55
56
  ### 1. init() - 初始化服务器
56
57
 
57
- 初始化服务器(必需,连接后必须先调用)。hash 相同则返回现有数据,hash 不同则删除旧服务器并重新创建。
58
+ 初始化服务器(必需,连接后必须先调用)。timestamp(在构造函数中传入)比现有的大则删除旧服务器并重新创建,否则返回现有数据。
58
59
 
59
60
  ```javascript
60
61
  server.init({
61
- hash: 'game-version-hash-123', // 必需:游戏版本哈希值
62
62
  world: { score: 0, level: 1 }, // 可选:世界初始数据
63
63
  self: {
64
64
  public: { name: 'Player1', x: 100, y: 100 } // 可选:公开数据
@@ -79,10 +79,10 @@ server.init({
79
79
 
80
80
  **注意:** `self` 和 `players[i]` 现在具有相同的结构,都只包含公开数据。
81
81
 
82
- **关于 hash:**
83
- - **hash 相同**:传入的值不生效,直接返回现有数据
84
- - **hash 不同**:删除旧服务器并重新创建,使用传入的值初始化数据
85
- - **何时更新 hash**:如果更改了游戏,且改动了角色或世界字段的设计(如新增/删除字段、改变字段类型),就需要更新 hash 让服务器重新初始化,避免数据结构不兼容
82
+ **关于 timestamp:**
83
+ - **timestamp 较小或相等**:传入的值不生效,直接返回现有数据
84
+ - **timestamp 较大**:删除旧服务器并重新创建,使用传入的值初始化数据
85
+ - **何时更新 timestamp**:如果更改了游戏,且改动了角色或世界字段的设计(如新增/删除字段、改变字段类型),就需要使用更大的 timestamp(上下文中会给出当前编辑时的timestamp)让服务器重新初始化,避免数据结构不兼容
86
86
 
87
87
  **注意:** init 成功后服务器每 0.2 秒自动推送最新数据
88
88
 
@@ -157,10 +157,10 @@ unsubscribe();
157
157
  ```javascript
158
158
  import { RiffleServer } from '@lzpenguin/server';
159
159
 
160
+ // post_id 和 token 会自动从浏览器 URL 参数中读取
160
161
  const server = new RiffleServer({
161
162
  url: 'wss://api.riffle.app',
162
- postId: 123456,
163
- token: 'your-token-here'
163
+ timestamp: 'timestamp given in the context'
164
164
  });
165
165
 
166
166
  // 监听服务器推送,更新游戏状态
@@ -182,7 +182,6 @@ server.onData((data) => {
182
182
 
183
183
  // 初始化游戏
184
184
  server.init({
185
- hash: 'v1.0.0',
186
185
  world: { score: 0, level: 1 },
187
186
  self: {
188
187
  public: { name: 'Player1', x: 0, y: 0 }
package/index.d.ts CHANGED
@@ -8,10 +8,8 @@
8
8
  export interface RiffleServerOptions {
9
9
  /** WebSocket 服务器 URL */
10
10
  url: string;
11
- /** 游戏贴文 ID */
12
- postId: number;
13
- /** 认证 token */
14
- token: string;
11
+ /** 游戏时间戳(用于判断是否需要重新初始化,新 timestamp 必须大于旧的才会重置) */
12
+ timestamp: number;
15
13
  /** 是否自动重连,默认 true */
16
14
  autoReconnect?: boolean;
17
15
  /** 重连间隔(毫秒),默认 3000 */
@@ -33,8 +31,6 @@ export interface PlayerSelfData {
33
31
  * 初始化数据
34
32
  */
35
33
  export interface InitData {
36
- /** 游戏版本哈希值(必需) */
37
- hash: string;
38
34
  /** 世界初始数据(可选) */
39
35
  world?: Record<string, any>;
40
36
  /** 玩家初始数据(可选) */
package/index.js CHANGED
@@ -37,8 +37,9 @@ if (typeof window !== 'undefined' && window.WebSocket) {
37
37
  *
38
38
  * const server = new RiffleServer({
39
39
  * url: 'wss://api.riffle.app',
40
- * postId: 123456,
41
- * token: 'your-token-here'
40
+ * timestamp: Date.now()
41
+ * // post_id 和 token 会自动从浏览器 URL 参数中读取
42
+ * // 例如:https://example.com/game.html?post_id=123456&token=xxx
42
43
  * });
43
44
  *
44
45
  * // 监听服务器推送的最新数据
@@ -69,28 +70,46 @@ if (typeof window !== 'undefined' && window.WebSocket) {
69
70
  export class RiffleServer {
70
71
  /**
71
72
  * @param {Object} options - 配置选项
72
- * @param {string} options.url - WebSocket 服务器 URL(例如:'wss://api.riffle.app' 或 'ws://localhost:8000'
73
- * @param {number} options.postId - 游戏贴文 ID
74
- * @param {string} options.token - 认证 token
73
+ * @param {string} options.url - WebSocket 服务器 URL(例如:'wss://api.riffle.app')
74
+ * @param {number} options.timestamp - 游戏时间戳(用于判断是否需要重新初始化,新 timestamp 必须大于旧的才会重置)
75
75
  * @param {boolean} [options.autoReconnect=true] - 是否自动重连
76
76
  * @param {number} [options.reconnectInterval=3000] - 重连间隔(毫秒)
77
77
  */
78
78
  constructor(options) {
79
- const { url, postId, token, autoReconnect = true, reconnectInterval = 3000 } = options;
79
+ const { url, timestamp, autoReconnect = true, reconnectInterval = 3000 } = options;
80
80
 
81
81
  if (!url) {
82
82
  throw new Error('URL is required');
83
83
  }
84
+ if (!timestamp) {
85
+ throw new Error('timestamp is required');
86
+ }
87
+
88
+ // 从浏览器 URL 参数中读取 post_id 和 token
89
+ let postId;
90
+ let token;
91
+
92
+ if (isBrowser && typeof window !== 'undefined' && window.location) {
93
+ const urlParams = new URLSearchParams(window.location.search);
94
+ if (urlParams.has('post_id')) {
95
+ postId = parseInt(urlParams.get('post_id'), 10);
96
+ }
97
+ if (urlParams.has('token')) {
98
+ token = urlParams.get('token');
99
+ }
100
+ }
101
+
84
102
  if (!postId) {
85
- throw new Error('postId is required');
103
+ throw new Error('post_id not found in browser URL parameters. Please ensure URL contains ?post_id=xxx');
86
104
  }
87
105
  if (!token) {
88
- throw new Error('token is required');
106
+ throw new Error('token not found in browser URL parameters. Please ensure URL contains &token=xxx');
89
107
  }
90
108
 
91
109
  this.url = url;
92
110
  this.postId = postId;
93
111
  this.token = token;
112
+ this.timestamp = timestamp;
94
113
  this.autoReconnect = autoReconnect;
95
114
  this.reconnectInterval = reconnectInterval;
96
115
 
@@ -264,7 +283,6 @@ export class RiffleServer {
264
283
  /**
265
284
  * 初始化服务器(必需,连接后必须先调用)
266
285
  * @param {Object} initData - 初始化数据
267
- * @param {string} initData.hash - 游戏版本哈希值(必需)
268
286
  * @param {Object} [initData.world] - 世界初始数据(可选)
269
287
  * @param {Object} [initData.self] - 玩家初始数据(可选)
270
288
  * @param {Object} [initData.self.public] - 公开数据(可选,旧格式)
@@ -272,7 +290,6 @@ export class RiffleServer {
272
290
  * @example
273
291
  * // 推荐:直接传递公开数据
274
292
  * server.init({
275
- * hash: 'game-version-hash-123',
276
293
  * world: { score: 0, level: 1 },
277
294
  * self: {
278
295
  * public: { name: 'Player1', x: 100, y: 100 }
@@ -282,19 +299,13 @@ export class RiffleServer {
282
299
  * @example
283
300
  * // 也支持直接传递对象(服务端会将其作为 public 数据处理)
284
301
  * server.init({
285
- * hash: 'game-version-hash-123',
286
302
  * world: { score: 0 },
287
303
  * self: {
288
304
  * public: { name: 'Player1' }
289
305
  * }
290
306
  * });
291
307
  */
292
- init(initData) {
293
- if (!initData || !initData.hash) {
294
- console.error('[RiffleServer] hash is required for init');
295
- return;
296
- }
297
-
308
+ init(initData = {}) {
298
309
  // 如果还未连接,保存 init 请求,连接建立后自动执行
299
310
  if (!this.isConnected || this.ws?.readyState !== WebSocketImpl.OPEN) {
300
311
  console.log('[RiffleServer] Not connected yet, will init after connection');
@@ -314,7 +325,7 @@ export class RiffleServer {
314
325
  _doInit(initData) {
315
326
  try {
316
327
  const initMessage = {
317
- hash: initData.hash,
328
+ timestamp: this.timestamp,
318
329
  world: initData.world || undefined,
319
330
  self: initData.self || undefined
320
331
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lzpenguin/server",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Riffle 游戏服务器 WebSocket 客户端 SDK",
5
5
  "license": "ISC",
6
6
  "author": "lzpenguin",