jake
4 years ago
21 changed files with 282 additions and 301 deletions
-
1Cargo.toml
-
4src/bin/login.rs
-
3src/bin/main.rs
-
3src/bin/ship.rs
-
2src/common/interserver.rs
-
2src/entity/gateway/entitygateway.rs
-
7src/entity/gateway/inmemory.rs
-
8src/entity/gateway/postgres/postgres.rs
-
58src/login/character.rs
-
20src/login/login.rs
-
112src/login_main.rs
-
44src/patch_main.rs
-
24src/ship/items/manager.rs
-
66src/ship/monster.rs
-
2src/ship/packet/handler/direct_message.rs
-
2src/ship/packet/handler/message.rs
-
5src/ship/packet/handler/room.rs
-
3src/ship/room.rs
-
105src/ship/ship.rs
-
8tests/common.rs
-
104tests/test_rooms.rs
@ -1,112 +0,0 @@ |
|||||
#![feature(const_generics)]
|
|
||||
|
|
||||
mod common;
|
|
||||
mod login;
|
|
||||
mod entity;
|
|
||||
|
|
||||
use std::thread;
|
|
||||
use std::collections::HashMap;
|
|
||||
|
|
||||
use bcrypt;
|
|
||||
|
|
||||
use libpso::character::settings;
|
|
||||
use libpso::character::character as pso_character;
|
|
||||
use libpso::character::guildcard;
|
|
||||
use libpso::{utf8_to_array, utf8_to_utf16_array};
|
|
||||
|
|
||||
use entity::gateway::EntityGateway;
|
|
||||
use entity::account::{UserAccount, UserSettings, GuildCardData};
|
|
||||
use entity::character::Character;
|
|
||||
|
|
||||
use login::login::LoginServerState;
|
|
||||
use login::character::CharacterServerState;
|
|
||||
|
|
||||
use std::time::SystemTime;
|
|
||||
|
|
||||
#[derive(Clone)]
|
|
||||
struct LoginStubData {
|
|
||||
users: HashMap<String, UserAccount>,
|
|
||||
characters: [Option<Character> ;4],
|
|
||||
}
|
|
||||
|
|
||||
impl LoginStubData {
|
|
||||
fn new() -> LoginStubData {
|
|
||||
let mut c = pso_character::Character::default();
|
|
||||
c.name = utf8_to_utf16_array!("Test Char", 16);
|
|
||||
|
|
||||
let mut users = HashMap::new();
|
|
||||
users.insert("hi".to_string(), UserAccount {
|
|
||||
id: 1,
|
|
||||
username: "hi".to_owned(),
|
|
||||
password: bcrypt::hash("qwer", 5).unwrap(),
|
|
||||
guildcard: None,
|
|
||||
team_id: None,
|
|
||||
banned: false,
|
|
||||
muted_until: SystemTime::now(),
|
|
||||
created_at: SystemTime::now(),
|
|
||||
flags: 0,
|
|
||||
});
|
|
||||
|
|
||||
LoginStubData {
|
|
||||
users: users,
|
|
||||
|
|
||||
characters: [Some(Character {
|
|
||||
id: 1,
|
|
||||
slot: 0,
|
|
||||
user_id: 1,
|
|
||||
character: c,
|
|
||||
}),
|
|
||||
None, None, None]
|
|
||||
}
|
|
||||
}
|
|
||||
}
|
|
||||
|
|
||||
impl EntityGateway for LoginStubData {
|
|
||||
fn get_user_by_name(&self, username: String) -> Option<UserAccount> {
|
|
||||
self.users.get(&username).map(|user| user.clone())
|
|
||||
}
|
|
||||
|
|
||||
fn get_user_settings_by_user(&self, user: &UserAccount) -> Option<UserSettings> {
|
|
||||
Some(UserSettings {
|
|
||||
id: 0,
|
|
||||
user_id: user.id,
|
|
||||
settings: settings::UserSettings::default()
|
|
||||
})
|
|
||||
}
|
|
||||
|
|
||||
fn set_user(&mut self, user: &UserAccount) {
|
|
||||
self.users.insert(user.username.clone(), user.clone());
|
|
||||
}
|
|
||||
|
|
||||
fn get_characters_by_user(&self, _user: &UserAccount) -> [Option<Character>; 4] {
|
|
||||
self.characters
|
|
||||
}
|
|
||||
|
|
||||
fn set_character(&mut self, char: &Character) {
|
|
||||
self.characters[char.slot as usize] = Some(char.clone());
|
|
||||
}
|
|
||||
|
|
||||
fn get_guild_card_data_by_user(&self, user: &UserAccount) -> GuildCardData {
|
|
||||
GuildCardData {
|
|
||||
id: 1,
|
|
||||
user_id: user.id,
|
|
||||
guildcard: guildcard::GuildCardData::default(),
|
|
||||
}
|
|
||||
}
|
|
||||
}
|
|
||||
|
|
||||
fn main() {
|
|
||||
println!("[login+character] starting server");
|
|
||||
|
|
||||
let auth_thread = thread::spawn(|| {
|
|
||||
let auth_state = LoginServerState::new(LoginStubData::new());
|
|
||||
common::mainloop::mainloop(auth_state, login::login::LOGIN_PORT);
|
|
||||
});
|
|
||||
let char_thread = thread::spawn(|| {
|
|
||||
let char_state = CharacterServerState::new(LoginStubData::new());
|
|
||||
common::mainloop::mainloop(char_state, login::character::CHARACTER_PORT);
|
|
||||
});
|
|
||||
|
|
||||
auth_thread.join().unwrap();
|
|
||||
char_thread.join().unwrap();
|
|
||||
}
|
|
@ -1,44 +0,0 @@ |
|||||
#![feature(const_generics)]
|
|
||||
|
|
||||
mod common;
|
|
||||
mod patch;
|
|
||||
use crate::patch::patch::{PatchServerState, PatchTreeIterItem, generate_patch_tree, load_config, load_motd};
|
|
||||
|
|
||||
fn main() {
|
|
||||
println!("[patch] starting server");
|
|
||||
|
|
||||
let patch_config = load_config();
|
|
||||
let patch_motd: String = load_motd();
|
|
||||
|
|
||||
if let Err(_) = std::fs::read_dir(patch_config.path.as_str()) {
|
|
||||
println!("Patch directory {} does not exist. Attempting to create it...", patch_config.path.as_str());
|
|
||||
if let Err(err) = std::fs::create_dir(patch_config.path.as_str()) {
|
|
||||
panic!("Failed to create patch directory! \n{}", err);
|
|
||||
}
|
|
||||
}
|
|
||||
|
|
||||
let (patch_file_tree, patch_file_lookup) = generate_patch_tree(patch_config.path.as_str());
|
|
||||
println!("[patch] files to patch:");
|
|
||||
let mut indent = 0;
|
|
||||
for item in patch_file_tree.flatten() {
|
|
||||
match item {
|
|
||||
PatchTreeIterItem::Directory(path) => {
|
|
||||
let s = path.to_str().unwrap();
|
|
||||
println!("{: >2$}\u{2517}\u{2500}\u{2500} {}", "", s, indent * 4);
|
|
||||
indent += 1;
|
|
||||
},
|
|
||||
PatchTreeIterItem::File(path, id) => {
|
|
||||
let s = path.to_str().unwrap();
|
|
||||
println!("{: >3$}\u{2520}\u{2500}\u{2500} {} ({})", "", s, id, indent * 4);
|
|
||||
},
|
|
||||
PatchTreeIterItem::UpDirectory => {
|
|
||||
indent -= 1;
|
|
||||
}
|
|
||||
}
|
|
||||
}
|
|
||||
|
|
||||
let patch_state = PatchServerState::new(patch_file_tree, patch_file_lookup, patch_motd);
|
|
||||
common::mainloop::mainloop(patch_state, patch_config.port);
|
|
||||
|
|
||||
println!("[patch] exiting...");
|
|
||||
}
|
|
@ -0,0 +1,104 @@ |
|||||
|
use elseware::common::serverstate::{ClientId, ServerState};
|
||||
|
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
|
||||
|
use elseware::entity::item;
|
||||
|
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
|
||||
|
|
||||
|
use libpso::packet::ship::*;
|
||||
|
use libpso::packet::messages::*;
|
||||
|
|
||||
|
#[path = "common.rs"]
|
||||
|
mod common;
|
||||
|
use common::*;
|
||||
|
|
||||
|
|
||||
|
#[async_std::test]
|
||||
|
async fn test_item_ids_reset_when_rejoining_rooms() {
|
||||
|
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
|
||||
|
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
|
||||
|
|
||||
|
for slot in 0..3 {
|
||||
|
entity_gateway.create_item(
|
||||
|
item::NewItemEntity {
|
||||
|
item: item::ItemDetail::Weapon(
|
||||
|
item::weapon::Weapon {
|
||||
|
weapon: item::weapon::WeaponType::Saber,
|
||||
|
grind: 0,
|
||||
|
special: None,
|
||||
|
attrs: [None, None, None],
|
||||
|
tekked: true,
|
||||
|
modifiers: Vec::new(),
|
||||
|
}
|
||||
|
),
|
||||
|
location: item::ItemLocation::Inventory {
|
||||
|
character_id: char1.id,
|
||||
|
slot: slot,
|
||||
|
equipped: false,
|
||||
|
}
|
||||
|
}).await.unwrap();
|
||||
|
}
|
||||
|
|
||||
|
for slot in 0..10 {
|
||||
|
entity_gateway.create_item(
|
||||
|
item::NewItemEntity {
|
||||
|
item: item::ItemDetail::Weapon(
|
||||
|
item::weapon::Weapon {
|
||||
|
weapon: item::weapon::WeaponType::Saber,
|
||||
|
grind: 0,
|
||||
|
special: None,
|
||||
|
attrs: [None, None, None],
|
||||
|
tekked: true,
|
||||
|
modifiers: Vec::new(),
|
||||
|
}
|
||||
|
),
|
||||
|
location: item::ItemLocation::Inventory {
|
||||
|
character_id: char2.id,
|
||||
|
slot: slot,
|
||||
|
equipped: false,
|
||||
|
}
|
||||
|
}).await.unwrap();
|
||||
|
}
|
||||
|
|
||||
|
let mut ship = ShipServerState::builder()
|
||||
|
.gateway(entity_gateway.clone())
|
||||
|
.build();
|
||||
|
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
|
log_in_char(&mut ship, ClientId(2), "a2", "a").await;
|
||||
|
|
||||
|
join_lobby(&mut ship, ClientId(1)).await;
|
||||
|
join_lobby(&mut ship, ClientId(2)).await;
|
||||
|
|
||||
|
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
let p = ship.handle(ClientId(2), &RecvShipPacket::MenuSelect(MenuSelect {
|
||||
|
menu: ROOM_MENU_ID,
|
||||
|
item: 0,
|
||||
|
})).await.unwrap().collect::<Vec<_>>();
|
||||
|
ship.handle(ClientId(2), &RecvShipPacket::DoneBursting(DoneBursting {})).await.unwrap().for_each(drop);
|
||||
|
|
||||
|
match &p[1].1 {
|
||||
|
SendShipPacket::AddToRoom(add_to) => {
|
||||
|
println!("addto {:?}", add_to);
|
||||
|
assert_eq!(add_to.playerinfo.inventory.items.iter().map(|k| k.item_id).collect::<Vec<_>>(),
|
||||
|
vec![0x210000,0x210001,0x210002,0x210003,0x210004,0x210005,0x210006,0x210007,0x210008,0x210009,
|
||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
|
||||
|
},
|
||||
|
_ => panic!(),
|
||||
|
}
|
||||
|
|
||||
|
leave_room(&mut ship, ClientId(2)).await;
|
||||
|
|
||||
|
let p = ship.handle(ClientId(2), &RecvShipPacket::MenuSelect(MenuSelect {
|
||||
|
menu: ROOM_MENU_ID,
|
||||
|
item: 0,
|
||||
|
})).await.unwrap().collect::<Vec<_>>();
|
||||
|
|
||||
|
match &p[1].1 {
|
||||
|
SendShipPacket::AddToRoom(add_to) => {
|
||||
|
assert_eq!(add_to.playerinfo.inventory.items.iter().map(|k| k.item_id).collect::<Vec<_>>(),
|
||||
|
vec![0x210000,0x210001,0x210002,0x210003,0x210004,0x210005,0x210006,0x210007,0x210008,0x210009,
|
||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
|
||||
|
},
|
||||
|
_ => panic!(),
|
||||
|
}
|
||||
|
}
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue