Skip to content

Commit

Permalink
Update SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
DogLooksGood committed Dec 25, 2023
1 parent 7de7ade commit fb57b4c
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 198 deletions.
1 change: 1 addition & 0 deletions core/src/types/transactor_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ pub enum BroadcastFrame {
game_addr: String,
event: Event,
timestamp: u64,
is_history: bool,
},
// Arbitrary message
Message {
Expand Down
45 changes: 33 additions & 12 deletions js/sdk-core/src/app-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { SdkError } from './error';
import { EntryType, EntryTypeCash, GameAccount, GameBundle, IToken, PlayerProfile } from './accounts';
import { TxState } from './tx-state';
import { Client } from './client';
import { Custom, GameEvent, ICustomEvent } from './events';
import { Custom, GameEvent, ICustomEvent, Sync } from './events';
import { ProfileCache } from './profile-cache';
import { IStorage, getTtlCache, setTtlCache } from './storage';
import { DecryptionCache } from './decryption-cache';
Expand All @@ -31,7 +31,8 @@ const BUNDLE_CACHE_TTL = 3600 * 365;
export type EventCallbackFunction = (
context: GameContextSnapshot,
state: Uint8Array,
event: GameEvent | undefined
event: GameEvent | undefined,
isHistory: boolean,
) => void;
export type MessageCallbackFunction = (message: Message) => void;
export type TxStateCallbackFunction = (txState: TxState) => void;
Expand Down Expand Up @@ -228,17 +229,17 @@ export class AppClient {
return await this.#profileCaches.getProfile(addr);
}

async invokeEventCallback(event: GameEvent | undefined) {
async invokeEventCallback(event: GameEvent | undefined, isHistory: boolean) {
const snapshot = new GameContextSnapshot(this.#gameContext);
const state = this.#gameContext.handlerState;
this.#onEvent(snapshot, state, event);
this.#onEvent(snapshot, state, event, isHistory);
}

async __initializeState(gameAccount: GameAccount): Promise<void> {
const initAccount = InitAccount.createFromGameAccount(gameAccount, this.gameContext.accessVersion, this.gameContext.settleVersion);
console.log('Initialize state with', initAccount);
await this.#handler.initState(this.#gameContext, initAccount);
await this.invokeEventCallback(undefined);
await this.invokeEventCallback(undefined, true);
}

async __getGameAccount(): Promise<GameAccount> {
Expand Down Expand Up @@ -308,12 +309,27 @@ export class AppClient {
this.#gameContext.prepareForNextEvent(timestamp);
try {
let context = new GameContext(this.#gameContext);
if (event instanceof Sync) {

while (true) {
let gameAccount = await this.#transport.getGameAccount(this.#gameAddr);
if (gameAccount === undefined) {
console.warn('Failed to get game account, will retry');
await new Promise(r => setTimeout(r, 3000));
continue;
}
for (const p of gameAccount.players) {
context.pushIdAddrPair(p.accessVersion, p.addr);
}
break;
}
}
await this.#handler.handleEvent(context, event);
this.#gameContext = context;
} catch (err: any) {
console.error(err);
}
await this.invokeEventCallback(event);
await this.invokeEventCallback(event, frame.isHistory);
} catch (e: any) {
console.log("Game context in error:", this.#gameContext);
throw e;
Expand Down Expand Up @@ -406,7 +422,8 @@ export class AppClient {
submitEvent(customEvent: ICustomEvent): Promise<void>;
async submitEvent(arg: ICustomEvent | Uint8Array): Promise<void> {
let raw = arg instanceof Uint8Array ? arg : arg.serialize();
const event = new Custom({ sender: this.playerAddr, raw });
const id = this.#gameContext.addrToId(this.playerAddr);
const event = new Custom({ sender: id, raw });
const connState = await this.#connection.submitEvent(
new SubmitEventParams({
event,
Expand All @@ -431,6 +448,15 @@ export class AppClient {
}
}

/**
* Parse the id to player's address.
*
* Throw an error when it fails.
*/
idToAddr(id: bigint): string {
return this.#gameContext.idToAddr(id)
}

/**
* Get hidden knowledge by random id. The result contains both
* public and private information. For performance reason, it's
Expand All @@ -441,11 +467,6 @@ export class AppClient {
return this.#decryptionCache.get(randomId) || new Map();
}

/**
* Close current event subscription.
*/
async close() {}

/**
* Exit current game.
*/
Expand Down
13 changes: 3 additions & 10 deletions js/sdk-core/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AttachGameParams, IConnection, SubmitEventParams } from './connection';
import { IEncryptor } from './encryptor';
import { SecretState } from './secret-state';
import { makeCustomEvent } from './events';
import { GameContext } from './game-context';
import { GameContext, IdAddrPair } from './game-context';
import { Id } from './types';

type OpIdent =
Expand Down Expand Up @@ -32,6 +32,7 @@ export class Client {
#addr: string;
#opHist: OpIdent[];
#secretState: SecretState;
#id: bigint;

constructor(addr: string, gameAddr: string, encryptor: IEncryptor, connection: IConnection) {
this.#addr = addr;
Expand All @@ -40,6 +41,7 @@ export class Client {
this.#connection = connection;
this.#opHist = new Array();
this.#secretState = new SecretState(encryptor);
this.#id = 0n;
}

async attachGame(): Promise<void> {
Expand All @@ -60,15 +62,6 @@ export class Client {
);
}

async submitCustomEvent(customEvent: any): Promise<void> {
const event = makeCustomEvent(this.#gameAddr, customEvent);
await this.#connection.submitEvent(
new SubmitEventParams({
event,
})
);
}

async handleDecision(ctx: GameContext): Promise<Event[]> {
return [];
}
Expand Down
2 changes: 2 additions & 0 deletions js/sdk-core/src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export class BroadcastFrameEvent extends BroadcastFrame {
event!: GameEvent;
@field('u64')
timestamp!: bigint;
@field('bool')
isHistory!: boolean;
constructor(fields: any) {
super();
Object.assign(this, fields);
Expand Down
8 changes: 4 additions & 4 deletions js/sdk-core/src/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ export class Release {
}

export class ActionTimeout {
@field('string')
playerAddr!: string;
@field('u64')
playerId!: bigint;
@field('u64')
timeout!: bigint;
constructor(fields: Fields<ActionTimeout>) {
Expand All @@ -115,8 +115,8 @@ export class ActionTimeout {
}

export class GamePlayer {
@field('string')
addr!: string;
@field('u64')
id!: bigint;
@field('u16')
position!: number;
@field('u64')
Expand Down
44 changes: 21 additions & 23 deletions js/sdk-core/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ export abstract class GameEvent implements IEventKind {

@variant(0)
export class Custom extends GameEvent implements IEventKind {
@field('string')
sender!: string;
@field('u64')
sender!: bigint;
@field('u8-array')
raw!: Uint8Array;
constructor(fields: EventFields<Custom>) {
Expand All @@ -94,7 +94,7 @@ export class Custom extends GameEvent implements IEventKind {
}
}

export function makeCustomEvent(sender: string, customEvent: ICustomEvent): Custom {
export function makeCustomEvent(sender: bigint, customEvent: ICustomEvent): Custom {
return new Custom({
sender,
raw: customEvent.serialize(),
Expand All @@ -113,8 +113,8 @@ export class Ready extends GameEvent implements IEventKind {

@variant(2)
export class ShareSecrets extends GameEvent implements IEventKind {
@field('string')
sender!: string;
@field('u64')
sender!: bigint;
@field(array(enums(SecretShare)))
shares!: SecretShare[];
constructor(fields: EventFields<ShareSecrets>) {
Expand All @@ -128,8 +128,8 @@ export class ShareSecrets extends GameEvent implements IEventKind {

@variant(3)
export class OperationTimeout extends GameEvent implements IEventKind {
@field(array('string'))
addrs!: string[];
@field(array('u64'))
ids!: bigint[];
constructor(fields: EventFields<OperationTimeout>) {
super();
Object.assign(this, fields);
Expand All @@ -141,8 +141,8 @@ export class OperationTimeout extends GameEvent implements IEventKind {

@variant(4)
export class Mask extends GameEvent implements IEventKind {
@field('string')
sender!: string;
@field('u64')
sender!: bigint;
@field('usize')
randomId!: Id;
@field(array('u8-array'))
Expand All @@ -168,8 +168,8 @@ export class CiphertextAndDigest {

@variant(5)
export class Lock extends GameEvent implements IEventKind {
@field('string')
sender!: string;
@field('u64')
sender!: bigint;
@field('usize')
randomId!: Id;
@field(array(struct(CiphertextAndDigest)))
Expand Down Expand Up @@ -211,10 +211,8 @@ export class Sync extends GameEvent implements IEventKind {

@variant(8)
export class ServerLeave extends GameEvent implements IEventKind {
@field('string')
serverAddr!: string;
@field('string')
transactorAddr!: string;
@field('u64')
serverId!: bigint;
constructor(fields: EventFields<ServerLeave>) {
super();
Object.assign(this, fields);
Expand All @@ -226,8 +224,8 @@ export class ServerLeave extends GameEvent implements IEventKind {

@variant(9)
export class Leave extends GameEvent implements IEventKind {
@field('string')
playerAddr!: string;
@field('u64')
playerId!: bigint;
constructor(fields: EventFields<Leave>) {
super();
Object.assign(this, fields);
Expand Down Expand Up @@ -262,8 +260,8 @@ export class WaitingTimeout extends GameEvent implements IEventKind {

@variant(12)
export class DrawRandomItems extends GameEvent implements IEventKind {
@field('string')
sender!: string;
@field('u64')
sender!: bigint;
@field('usize')
randomId!: Id;
@field(array('usize'))
Expand All @@ -289,8 +287,8 @@ export class DrawTimeout extends GameEvent implements IEventKind {

@variant(14)
export class ActionTimeout extends GameEvent implements IEventKind {
@field('string')
playerAddr!: string;
@field('u64')
playerId!: bigint;
constructor(fields: EventFields<ActionTimeout>) {
super();
Object.assign(this, fields);
Expand All @@ -302,8 +300,8 @@ export class ActionTimeout extends GameEvent implements IEventKind {

@variant(15)
export class AnswerDecision extends GameEvent implements IEventKind {
@field('string')
sender!: string;
@field('u64')
sender!: bigint;
@field('usize')
decisionId!: Id;
@field('u8-array')
Expand Down
Loading

0 comments on commit fb57b4c

Please sign in to comment.