chatchat/src/PlayerIOClient.ts

171 lines
4.8 KiB
TypeScript

type Settings = {
apiRoot: string,
}
export const settings: Settings = {
apiRoot: "https://api.playerio.com/json/",
}
type KVPair = {
key: string,
value: string,
}
const map2KV = function(rec: Record<string, any>): Array<KVPair> {
return Object.entries(rec).map(([key, value]) => {
return {
key: key,
value: value,
}
})
}
const kv2Map = function(kv: Array<KVPair>): Record<string, any> {
let obj: Record<string, any> = {}
kv.forEach(p => {
obj[p.key] = p.value
})
return obj
}
class Channel {
token: string | undefined
call<A>(method: number, args: Record<string, any>, converter: (response: Record<string, any>) => A): Promise<A> {
const body = "[" + method + "|" + (this.token || "") + "]" + JSON.stringify(args)
return fetch(settings.apiRoot, {
method: "POST",
body: body,
}).then(resp => resp.text()).then(resp => {
if(resp.startsWith("[")) {
const end = resp.indexOf("]")
this.token = resp.substring(1, end)
resp = resp.substring(end + 1)
}
return JSON.parse(resp)
}).then(result => {
return converter(result)
})
}
authenticate(
gameId: string,
connectionId: string,
authenticationArguments: Array<KVPair>,
playerInsightSegments: Array<string>,
clientApi: string,
clientInfo: Array<KVPair>,
playCodes: Array<string>,
converter: (response: Record<string, any>) => Client
): Promise<Client> {
return this.call(13, {
gameid: gameId,
connectionid: connectionId,
authenticationarguments: authenticationArguments,
playerinsightsegments: playerInsightSegments,
clientapi: clientApi,
clientinfo: clientInfo,
playcodes: playCodes
}, converter)
}
listRooms(
roomType: string,
searchCriteria: Record<string, any>,
resultLimit: number,
resultOffset: number,
onlyDevRooms: boolean,
converter: (response: Record<string, any>) => Array<RoomInfo>
): Promise<Array<RoomInfo>> {
return this.call(30, {
roomtype: roomType,
searchcriteria: searchCriteria,
resultlimit: resultLimit,
resultoffset: resultOffset,
onlydevrooms: onlyDevRooms
}, converter)
}
}
export const authenticate = function (
gameId: string,
connectionId: string,
authenticationArguments: Record<string, string>,
playerInsightSegments: Array<string>,
): Promise<Client> {
const channel = new Channel();
return channel.authenticate(
gameId,
connectionId,
map2KV(authenticationArguments),
playerInsightSegments,
"javascript",
map2KV({}),
[],
(result: Record<string, any>) => {
channel.token = result.token;
return new Client(channel, gameId, result.gamefsredirectmap, result.userid);
}
)
}
export class Client {
connectUserId: string
gameId: string
multiplayer: Multiplayer
constructor(channel: Channel, gameId: string, gameFsRedirectMap: string, userId: string) {
this.connectUserId = userId;
this.gameId = gameId;
this.multiplayer = new Multiplayer(channel)
}
}
export class Multiplayer {
developmentServer: string | null
useSecureConnections: boolean
listRooms: (roomType: string, searchCriteria: Record<string, any>, resultLimit: number, resultOffset: number) => Promise<Array<RoomInfo>>
constructor(channel: Channel) {
this.developmentServer = null
this.useSecureConnections = true
this.listRooms = (roomType: string, searchCriteria: Record<string, any>, resultLimit: number, resultOffset: number) =>
channel.listRooms(
roomType,
map2KV(searchCriteria),
resultLimit,
resultOffset,
this.developmentServer != null,
(result: Record<string, any>) =>
result.rooms.map((room: any) =>
new RoomInfo(
room.id,
room.roomtype,
room.onlineusers,
kv2Map(room.roomdata)
)
)
)
}
}
class RoomInfo {
id: string
roomType: string
onlineUsers: number
roomData: Record<string, any>
constructor(id: string, roomType: string, onlineUsers: number, roomData: Record<string, any>) {
this.id = id
this.roomType = roomType
this.onlineUsers = onlineUsers
this.roomData = roomData
}
}