1use borsh::{BorshDeserialize, BorshSerialize};
2
3use crate::{
4 effect::Effect,
5 error::{HandleError, HandleResult},
6 event::Event,
7 prelude::ServerJoin,
8 types::PlayerJoin,
9};
10
11#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
15pub struct InitAccount {
16 pub addr: String,
17 pub players: Vec<PlayerJoin>,
18 pub servers: Vec<ServerJoin>,
19 pub data: Vec<u8>,
20 pub access_version: u64,
21 pub settle_version: u64,
22 pub max_players: u16,
23 pub checkpoint: Vec<u8>,
24}
25
26impl InitAccount {
27 pub fn data<S: BorshDeserialize>(&self) -> Result<S, HandleError> {
28 S::try_from_slice(&self.data).or(Err(HandleError::MalformedGameAccountData))
29 }
30
31 pub fn checkpoint<S: BorshDeserialize>(&self) -> Result<Option<S>, HandleError> {
32 if self.checkpoint.is_empty() {
33 Ok(None)
34 } else {
35 S::try_from_slice(&self.checkpoint).or(Err(HandleError::MalformedCheckpointData)).map(Some)
36 }
37 }
38
39 pub fn add_player<S: Into<String>>(
43 &mut self,
44 addr: S,
45 position: usize,
46 balance: u64,
47 verify_key: String,
48 ) {
49 self.access_version += 1;
50 let access_version = self.access_version;
51 if self.players.iter().any(|p| p.position as usize == position) {
52 panic!("Failed to add player, duplicated position");
53 }
54 self.players.push(PlayerJoin {
55 position: position as _,
56 balance,
57 addr: addr.into(),
58 access_version,
59 verify_key,
60 })
61 }
62}
63
64impl Default for InitAccount {
65 fn default() -> Self {
66 Self {
67 addr: "".into(),
68 players: Vec::new(),
69 servers: Vec::new(),
70 data: Vec::new(),
71 access_version: 0,
72 settle_version: 0,
73 max_players: 10,
74 checkpoint: Vec::new(),
75 }
76 }
77}
78
79pub trait GameHandler: Sized + BorshSerialize + BorshDeserialize {
80 type Checkpoint: BorshSerialize + BorshDeserialize;
81
82 fn init_state(effect: &mut Effect, init_account: InitAccount) -> HandleResult<Self>;
84
85 fn handle_event(&mut self, effect: &mut Effect, event: Event) -> HandleResult<()>;
87
88 fn into_checkpoint(self) -> HandleResult<Self::Checkpoint>;
90}