@oyna360/game-sdk 0.5.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 oyna360
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # @oyna360/game-sdk
2
+
3
+ SDK رسمی اتصال **بازی شما** به **پلتفرم oyna360**.
4
+
5
+ با این پکیج بازی می‌تواند:
6
+
7
+ - هویت بازیکن و سشن را بگیرد
8
+ - امتیاز، لیدربورد، دستاورد و کیف‌پول جِم را صدا بزند
9
+ - در **Production** داخل iframe پلتفرم کار کند
10
+ - در **Development** بدون iframe، مستقیم به سرور oyna360 وصل شود
11
+
12
+ **نسخه:** `0.5.1` · بدون وابستگی runtime · TypeScript داخل پکیج
13
+
14
+ > این SDK مسئول لابی ۳D نیست. برای لابی از [`@oyna360/lobby-sdk`](https://github.com/mamadjavadrasti/oyna360-lobby-sdk) استفاده کنید. این دو پکیج را ادغام نکنید.
15
+
16
+ ---
17
+
18
+ ## نصب
19
+
20
+ ```bash
21
+ npm install github:mamadjavadrasti/oyna360-game-sdk#v0.5.1
22
+ # یا
23
+ pnpm add github:mamadjavadrasti/oyna360-game-sdk#v0.5.1
24
+ ```
25
+
26
+ ```json
27
+ {
28
+ "dependencies": {
29
+ "@oyna360/game-sdk": "github:mamadjavadrasti/oyna360-game-sdk#v0.5.1"
30
+ }
31
+ }
32
+ ```
33
+
34
+ همیشه تگ نسخه‌ای را پین کنید که `dist/` داخل ریپو دارد.
35
+
36
+ ---
37
+
38
+ ## دو حالت اجرا
39
+
40
+ | حالت | چطور بازی باز می‌شود | `init()` از کجا Context می‌گیرد |
41
+ |------|----------------------|----------------------------------|
42
+ | **Production** | بازیکن از `https://oyna360.ir/play/{slug}` وارد می‌شود؛ بازی داخل iframe است | `postMessage` → `platform:init` از parent |
43
+ | **Direct Development** | شما `npm run dev` می‌زنید و بازی را مستقیم روی origin خودتان باز می‌کنید | Authorize با اکانت واقعی → سشن موقت → همان `SdkInitPayload` |
44
+
45
+ در هر دو حالت API بازی یکسان است:
46
+
47
+ ```ts
48
+ import { PlatformSDK } from '@oyna360/game-sdk';
49
+
50
+ const { user, game, session, avatar, lobby } = await PlatformSDK.init({
51
+ // فقط برای Direct Development لازم است:
52
+ // platformUrl: 'https://oyna360.ir/api',
53
+ // platformWebUrl: 'https://oyna360.ir',
54
+ // gameSlug: 'my-game',
55
+ });
56
+ ```
57
+
58
+ ---
59
+
60
+ ## شروع سریع — Production
61
+
62
+ 1. بازی را روی URL عمومی host کنید.
63
+ 2. در پنل ادمین oyna360: `slug`، `entryUrl`، `allowedOrigins`، `minSdkVersion`.
64
+ 3. بازیکن از `/play/{slug}` وارد شود.
65
+
66
+ ```ts
67
+ import { PlatformSDK } from '@oyna360/game-sdk';
68
+
69
+ async function boot() {
70
+ const { user, game } = await PlatformSDK.init({ timeout: 15_000 });
71
+ console.log(user.displayName, game.slug);
72
+
73
+ // گیم‌پلی…
74
+ await PlatformSDK.submitScore(4200);
75
+ await PlatformSDK.endSession();
76
+ }
77
+
78
+ boot().catch(console.error);
79
+ ```
80
+
81
+ ---
82
+
83
+ ## شروع سریع — Direct Development
84
+
85
+ بدون کلون کردن پلتفرم:
86
+
87
+ ```ts
88
+ await PlatformSDK.init({
89
+ platformUrl: 'https://oyna360.ir/api',
90
+ platformWebUrl: 'https://oyna360.ir',
91
+ gameSlug: 'my-game',
92
+ });
93
+ ```
94
+
95
+ یا قبل از `init`:
96
+
97
+ ```ts
98
+ window.__OYNA360_DEV__ = {
99
+ platformUrl: 'https://oyna360.ir/api',
100
+ platformWebUrl: 'https://oyna360.ir',
101
+ gameSlug: 'my-game',
102
+ };
103
+ await PlatformSDK.init();
104
+ ```
105
+
106
+ پنجرهٔ ورود oyna360 باز می‌شود؛ با اکانت واقعی وارد می‌شوید؛ SDK Context کامل (شامل `avatar` و `lobby`) را می‌گیرد.
107
+
108
+ در Direct Development همان APIهای امتیاز، لیدربورد، دستاورد و کیف‌پول از طریق REST مستقیم به `platformUrl` صدا زده می‌شوند (بدون iframe). Origin بازی باید در `DEV_GAME_ORIGINS` / `allowedOrigins` و CORS باشد.
109
+
110
+ جزئیات و تنظیم Origin: [docs/09-direct-development.md](./docs/09-direct-development.md)
111
+
112
+ ---
113
+
114
+ ## مستندات
115
+
116
+ | موضوع | فایل |
117
+ |--------|------|
118
+ | این SDK چیست / مرز با lobby-sdk | [docs/00-overview.md](./docs/00-overview.md) |
119
+ | نصب و پیش‌نیاز ادمین | [docs/01-shoro.md](./docs/01-shoro.md) |
120
+ | `init()` و `SdkInitPayload` | [docs/02-init.md](./docs/02-init.md) |
121
+ | user / session | [docs/03-user-session.md](./docs/03-user-session.md) |
122
+ | پایان سشن | [docs/04-end-session.md](./docs/04-end-session.md) |
123
+ | امتیاز | [docs/05-scores.md](./docs/05-scores.md) |
124
+ | لیدربورد | [docs/06-leaderboard.md](./docs/06-leaderboard.md) |
125
+ | پروتکل postMessage | [docs/07-postmessage-protocol.md](./docs/07-postmessage-protocol.md) |
126
+ | جِم و سکه | [docs/08-wallet.md](./docs/08-wallet.md) |
127
+ | Direct Development Mode | [docs/09-direct-development.md](./docs/09-direct-development.md) |
128
+ | دستاوردها | [docs/10-achievements.md](./docs/10-achievements.md) |
129
+ | عیب‌یابی | [docs/11-troubleshooting.md](./docs/11-troubleshooting.md) |
130
+
131
+ ---
132
+
133
+ ## API خلاصه
134
+
135
+ | متد | توضیح | Production | Direct Dev |
136
+ |-----|--------|:----------:|:----------:|
137
+ | `init(options?)` | دریافت Context پلتفرم | ✅ | ✅ |
138
+ | `getUser()` / `getSession()` / `getInitPayload()` / `isReady()` | خواندن وضعیت | ✅ | ✅ |
139
+ | `endSession()` | بستن سشن | ✅ | ✅ |
140
+ | `submitScore` / `getLeaderboard` | امتیاز | ✅ | ✅ |
141
+ | `unlockAchievement` / `getAchievements` | دستاورد | ✅ | ✅ |
142
+ | `getWallet` / `convertGems` | جِم | ✅ | ✅ |
143
+
144
+ Production از `postMessage` به parent استفاده می‌کند؛ Direct Dev همان endpointهای REST را با session token صدا می‌زند.
145
+
146
+ `PlatformSDK.version` → `'0.5.1'`
147
+
148
+ ---
149
+
150
+ ## اتصال به lobby-sdk
151
+
152
+ بعد از `init()`:
153
+
154
+ ```ts
155
+ import { PlatformSDK } from '@oyna360/game-sdk';
156
+ import { PlatformLobby } from '@oyna360/lobby-sdk';
157
+
158
+ const init = await PlatformSDK.init({ /* … */ });
159
+ const lobby = await PlatformLobby.create({
160
+ canvas,
161
+ platformInit: init,
162
+ roomId: init.lobby!.roomId,
163
+ wsUrl: init.lobby!.wsUrl,
164
+ });
165
+ ```
166
+
167
+ `lobby.wsUrl` را هاردکد نکنید.
168
+
169
+ ---
170
+
171
+ ## لایسنس
172
+
173
+ MIT
@@ -0,0 +1,56 @@
1
+ import { SDK_VERSION, type PlatformInitMessage, type PlatformSdkInitOptions, type AchievementsResponse, type SdkInitPayload, type SdkSession, type SdkUser, type LeaderboardResponse, type SubmitScoreResponse, type UnlockAchievementResponse, type WalletBalanceResponse, type ConvertGemsResponse } from './types';
2
+ export { SDK_VERSION };
3
+ export type { SdkInitPayload, SdkLobbyAvatar, SdkSession, SdkUser, SdkGameInfo, PlatformInitMessage, PlatformSdkInitOptions, LeaderboardEntry, LeaderboardResponse, SubmitScoreResponse, AchievementItem, AchievementsResponse, UnlockAchievementResponse, WalletBalanceResponse, ConvertGemsResponse, } from './types';
4
+ declare global {
5
+ interface Window {
6
+ __OYNA360_PLATFORM_INIT__?: PlatformInitMessage;
7
+ __OYNA360_DEV__?: {
8
+ platformUrl?: string;
9
+ platformWebUrl?: string;
10
+ gameSlug?: string;
11
+ };
12
+ }
13
+ }
14
+ /**
15
+ * Wait for platform init payload.
16
+ * - Production iframe: receives `platform:init` from parent.
17
+ * - Direct Development: Oyna360 authorize → one-time code → standard SdkInitPayload.
18
+ */
19
+ export declare function init(options?: PlatformSdkInitOptions): Promise<SdkInitPayload>;
20
+ export declare function getUser(): SdkUser | null;
21
+ export declare function getSession(): SdkSession | null;
22
+ export declare function getInitPayload(): SdkInitPayload | null;
23
+ export declare function isReady(): boolean;
24
+ /** Submit score (keeps best score per player). Requires active session. */
25
+ export declare function submitScore(score: number): Promise<SubmitScoreResponse>;
26
+ /** Fetch game leaderboard via platform bridge (iframe) or REST (Direct Dev). */
27
+ export declare function getLeaderboard(limit?: number): Promise<LeaderboardResponse>;
28
+ /** Unlock an achievement for the current player. Idempotent. */
29
+ export declare function unlockAchievement(key: string): Promise<UnlockAchievementResponse>;
30
+ /** List achievements with unlock status for the current player. */
31
+ export declare function getAchievements(): Promise<AchievementsResponse>;
32
+ /** Platform gem balance + coins-per-gem rate for this game. */
33
+ export declare function getWallet(): Promise<WalletBalanceResponse>;
34
+ /**
35
+ * Convert platform gems into in-game coins.
36
+ * Platform deducts gems; the game must credit `coinsReceived` to its own economy.
37
+ */
38
+ export declare function convertGems(gems: number): Promise<ConvertGemsResponse>;
39
+ export declare function endSession(): Promise<void>;
40
+ export declare const PlatformSDK: {
41
+ version: string;
42
+ init: typeof init;
43
+ getUser: typeof getUser;
44
+ getSession: typeof getSession;
45
+ getInitPayload: typeof getInitPayload;
46
+ isReady: typeof isReady;
47
+ submitScore: typeof submitScore;
48
+ getLeaderboard: typeof getLeaderboard;
49
+ unlockAchievement: typeof unlockAchievement;
50
+ getAchievements: typeof getAchievements;
51
+ getWallet: typeof getWallet;
52
+ convertGems: typeof convertGems;
53
+ endSession: typeof endSession;
54
+ };
55
+ export default PlatformSDK;
56
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,cAAc,EAEnB,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,YAAY,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAQjB,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,yBAAyB,CAAC,EAAE,mBAAmB,CAAC;QAChD,eAAe,CAAC,EAAE;YAChB,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,cAAc,CAAC,EAAE,MAAM,CAAC;YACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH;CACF;AA6aD;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CAuDpF;AAED,wBAAgB,OAAO,IAAI,OAAO,GAAG,IAAI,CAExC;AAED,wBAAgB,UAAU,IAAI,UAAU,GAAG,IAAI,CAE9C;AAED,wBAAgB,cAAc,IAAI,cAAc,GAAG,IAAI,CAEtD;AAED,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,2EAA2E;AAC3E,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiB7E;AAED,gFAAgF;AAChF,wBAAsB,cAAc,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAa7E;AAED,gEAAgE;AAChE,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAiBvF;AAED,mEAAmE;AACnE,wBAAsB,eAAe,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAQrE;AAED,+DAA+D;AAC/D,wBAAsB,SAAS,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAQhE;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgB5E;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA0BhD;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;CAcvB,CAAC;AAEF,eAAe,WAAW,CAAC"}