agones.dev/agones@v1.54.0/sdks/rust/src/alpha.rs (about) 1 // Copyright 2020 Google LLC All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use crate::errors::Result; 16 use tonic::transport::Channel; 17 18 mod api { 19 tonic::include_proto!("agones.dev.sdk.alpha"); 20 } 21 22 use api::sdk_client::SdkClient; 23 24 /// Alpha is an instance of the Agones Alpha SDK 25 #[derive(Clone)] 26 pub struct Alpha { 27 client: SdkClient<Channel>, 28 } 29 30 impl Alpha { 31 /// new creates a new instance of the Alpha SDK 32 pub(crate) fn new(ch: Channel) -> Self { 33 Self { 34 client: SdkClient::new(ch), 35 } 36 } 37 38 /// This returns the last player capacity that was set through the SDK. 39 /// If the player capacity is set from outside the SDK, use 40 /// [`Sdk::get_gameserver`] instead. 41 #[inline] 42 pub async fn get_player_capacity(&mut self) -> Result<i64> { 43 Ok(self 44 .client 45 .get_player_capacity(api::Empty {}) 46 .await 47 .map(|c| c.into_inner().count)?) 48 } 49 50 /// This changes the player capacity to a new value. 51 #[inline] 52 pub async fn set_player_capacity(&mut self, count: i64) -> Result<()> { 53 Ok(self 54 .client 55 .set_player_capacity(api::Count { count }) 56 .await 57 .map(|_| ())?) 58 } 59 60 /// This function increases the SDK’s stored player count by one, and appends 61 /// this playerID to `GameServer.status.players.ids`. 62 /// 63 /// Returns true and adds the playerID to the list of playerIDs if the 64 /// playerIDs was not already in the list of connected playerIDs. 65 #[inline] 66 pub async fn player_connect(&mut self, id: impl Into<String>) -> Result<bool> { 67 Ok(self 68 .client 69 .player_connect(api::PlayerId { 70 player_id: id.into(), 71 }) 72 .await 73 .map(|b| b.into_inner().bool)?) 74 } 75 76 /// This function decreases the SDK’s stored player count by one, and removes 77 /// the playerID from GameServer.status.players.ids. 78 /// 79 /// Will return true and remove the supplied playerID from the list of 80 /// connected playerIDs if the playerID value exists within the list. 81 #[inline] 82 pub async fn player_disconnect(&mut self, id: impl Into<String>) -> Result<bool> { 83 Ok(self 84 .client 85 .player_disconnect(api::PlayerId { 86 player_id: id.into(), 87 }) 88 .await 89 .map(|b| b.into_inner().bool)?) 90 } 91 92 /// Returns the current player count. 93 #[inline] 94 pub async fn get_player_count(&mut self) -> Result<i64> { 95 Ok(self 96 .client 97 .get_player_count(api::Empty {}) 98 .await 99 .map(|c| c.into_inner().count)?) 100 } 101 102 /// This returns if the playerID is currently connected to the GameServer. 103 /// This is always accurate, even if the value hasn’t been updated to the 104 /// Game Server status yet. 105 #[inline] 106 pub async fn is_player_connected(&mut self, id: impl Into<String>) -> Result<bool> { 107 Ok(self 108 .client 109 .is_player_connected(api::PlayerId { 110 player_id: id.into(), 111 }) 112 .await 113 .map(|b| b.into_inner().bool)?) 114 } 115 116 /// This returns the list of the currently connected player ids. 117 /// This is always accurate, even if the value has not been updated to the 118 /// Game Server status yet. 119 #[inline] 120 pub async fn get_connected_players(&mut self) -> Result<Vec<String>> { 121 Ok(self 122 .client 123 .get_connected_players(api::Empty {}) 124 .await 125 .map(|pl| pl.into_inner().list)?) 126 } 127 } 128 129 130 #[cfg(test)] 131 mod tests { 132 use tokio; 133 134 // MockAlpha simulates Alpha's async methods for unit testing 135 struct MockAlpha { 136 capacity: i64, 137 player_count: i64, 138 player_connected: Option<String>, 139 player_disconnected: Option<String>, 140 } 141 142 impl MockAlpha { 143 fn new() -> Self { 144 Self { 145 capacity: 0, 146 player_count: 0, 147 player_connected: None, 148 player_disconnected: None, 149 } 150 } 151 152 async fn get_player_capacity(&mut self) -> i64 { 153 self.capacity 154 } 155 156 async fn set_player_capacity(&mut self, count: i64) { 157 self.capacity = count; 158 } 159 160 async fn player_connect(&mut self, id: impl Into<String>) -> bool { 161 let id = id.into(); 162 self.player_connected = Some(id.clone()); 163 self.player_count += 1; 164 true 165 } 166 167 async fn player_disconnect(&mut self, id: impl Into<String>) -> bool { 168 let id = id.into(); 169 self.player_disconnected = Some(id.clone()); 170 if self.player_count > 0 { 171 self.player_count -= 1; 172 } 173 true 174 } 175 176 async fn get_player_count(&mut self) -> i64 { 177 self.player_count 178 } 179 180 async fn is_player_connected(&mut self, id: impl Into<String>) -> bool { 181 match &self.player_connected { 182 Some(connected) => id.into() == *connected, 183 None => false, 184 } 185 } 186 187 async fn get_connected_players(&mut self) -> Vec<String> { 188 match &self.player_connected { 189 Some(id) => vec![id.clone()], 190 None => vec![], 191 } 192 } 193 } 194 195 #[tokio::test] 196 async fn test_alpha_player_flow() { 197 let mut alpha = MockAlpha::new(); 198 199 // Set and get player capacity 200 alpha.set_player_capacity(15).await; 201 assert_eq!(alpha.capacity, 15); 202 203 let capacity = alpha.get_player_capacity().await; 204 assert_eq!(capacity, 15); 205 206 // Connect player 207 let player_id = "one"; 208 let ok = alpha.player_connect(player_id).await; 209 assert!(ok); 210 assert_eq!(alpha.player_connected.as_deref(), Some(player_id)); 211 212 // Get player count 213 let count = alpha.get_player_count().await; 214 assert_eq!(count, 1); 215 216 // Disconnect player 217 let ok = alpha.player_disconnect(player_id).await; 218 assert!(ok); 219 assert_eq!(alpha.player_disconnected.as_deref(), Some(player_id)); 220 221 // Put the player back in 222 let ok = alpha.player_connect(player_id).await; 223 assert!(ok); 224 let count = alpha.get_player_count().await; 225 assert_eq!(count, 1); 226 227 // Is player connected (should be true) 228 let ok = alpha.is_player_connected(player_id).await; 229 assert!(ok, "Player should be connected"); 230 231 // Is player connected (should be false) 232 let ok = alpha.is_player_connected("false").await; 233 assert!(!ok, "Player should not be connected"); 234 235 // Get connected players 236 let list = alpha.get_connected_players().await; 237 assert_eq!(list, vec![player_id]); 238 } 239 }