|
@ -1,6 +1,8 @@ |
|
|
#![allow(dead_code, unused_assignments)]
|
|
|
#![allow(dead_code, unused_assignments)]
|
|
|
use std::io::Read;
|
|
|
use std::io::Read;
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
|
use std::collections::{BTreeMap, HashMap};
|
|
|
|
|
|
use std::net::Ipv4Addr;
|
|
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
|
use rand::Rng;
|
|
|
use rand::Rng;
|
|
|
use crc::{crc32, Hasher32};
|
|
|
use crc::{crc32, Hasher32};
|
|
@ -13,6 +15,7 @@ use libpso::character::character; |
|
|
|
|
|
|
|
|
use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
|
|
|
use crate::common::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
|
|
|
use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
|
|
|
use crate::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
|
|
|
|
|
|
use crate::common::interserver::{ServerId, InterserverActor, LoginMessage, ShipMessage, Ship};
|
|
|
use crate::common::leveltable::CharacterLevelTable;
|
|
|
use crate::common::leveltable::CharacterLevelTable;
|
|
|
use libpso::{utf8_to_array, utf8_to_utf16_array};
|
|
|
use libpso::{utf8_to_array, utf8_to_utf16_array};
|
|
|
|
|
|
|
|
@ -162,14 +165,14 @@ impl ClientState { |
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Ship {
|
|
|
|
|
|
|
|
|
/*struct Ship {
|
|
|
flags: u32,
|
|
|
flags: u32,
|
|
|
name: String,
|
|
|
name: String,
|
|
|
ip: [u8; 4],
|
|
|
ip: [u8; 4],
|
|
|
port: u16,
|
|
|
port: u16,
|
|
|
}
|
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
impl Ship {
|
|
|
|
|
|
|
|
|
/*impl Ship {
|
|
|
fn new(name: &str, ip: [u8; 4], port: u16) -> Ship {
|
|
|
fn new(name: &str, ip: [u8; 4], port: u16) -> Ship {
|
|
|
Ship {
|
|
|
Ship {
|
|
|
flags: 0,
|
|
|
flags: 0,
|
|
@ -178,14 +181,14 @@ impl Ship { |
|
|
port: port,
|
|
|
port: port,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
pub struct CharacterServerState<EG: EntityGateway> {
|
|
|
pub struct CharacterServerState<EG: EntityGateway> {
|
|
|
entity_gateway: EG,
|
|
|
entity_gateway: EG,
|
|
|
param_header: ParamDataHeader,
|
|
|
param_header: ParamDataHeader,
|
|
|
param_data: Vec<u8>,
|
|
|
param_data: Vec<u8>,
|
|
|
clients: HashMap<ClientId, ClientState>,
|
|
|
clients: HashMap<ClientId, ClientState>,
|
|
|
ships: Vec<Ship>,
|
|
|
|
|
|
|
|
|
ships: BTreeMap<ServerId, Ship>,
|
|
|
level_table: CharacterLevelTable,
|
|
|
level_table: CharacterLevelTable,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@ -293,16 +296,16 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
pub fn new(entity_gateway: EG) -> CharacterServerState<EG> {
|
|
|
pub fn new(entity_gateway: EG) -> CharacterServerState<EG> {
|
|
|
let (param_header, param_data) = generate_param_data("data/param/");
|
|
|
let (param_header, param_data) = generate_param_data("data/param/");
|
|
|
|
|
|
|
|
|
let ships = vec![Ship::new("Sona-Nyl", [127,0,0,1], 23423),
|
|
|
|
|
|
|
|
|
/*let ships = vec![Ship::new("Sona-Nyl", [127,0,0,1], 23423),
|
|
|
Ship::new("Dylath-Leen", [127,0,0,1], 23424),
|
|
|
Ship::new("Dylath-Leen", [127,0,0,1], 23424),
|
|
|
Ship::new("Thalarion", [127,0,0,1], 23425),
|
|
|
Ship::new("Thalarion", [127,0,0,1], 23425),
|
|
|
];
|
|
|
|
|
|
|
|
|
];*/
|
|
|
CharacterServerState {
|
|
|
CharacterServerState {
|
|
|
entity_gateway: entity_gateway,
|
|
|
entity_gateway: entity_gateway,
|
|
|
param_header: param_header,
|
|
|
param_header: param_header,
|
|
|
param_data: param_data,
|
|
|
param_data: param_data,
|
|
|
clients: HashMap::new(),
|
|
|
clients: HashMap::new(),
|
|
|
ships: ships,
|
|
|
|
|
|
|
|
|
ships: BTreeMap::new(),
|
|
|
level_table: CharacterLevelTable::new(),
|
|
|
level_table: CharacterLevelTable::new(),
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@ -326,10 +329,10 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
|
|
|
|
|
|
fn send_ship_list(&mut self, _id: ClientId, _pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
fn send_ship_list(&mut self, _id: ClientId, _pkt: &Login) -> Result<Vec<SendCharacterPacket>, CharacterError> {
|
|
|
Ok(vec![SendCharacterPacket::Timestamp(Timestamp::new(chrono::Utc::now())),
|
|
|
Ok(vec![SendCharacterPacket::Timestamp(Timestamp::new(chrono::Utc::now())),
|
|
|
SendCharacterPacket::ShipList(ShipList::new(self.ships.iter().enumerate().map(|(i, s)| {
|
|
|
|
|
|
|
|
|
SendCharacterPacket::ShipList(ShipList::new(self.ships.iter().map(|(i, s)| {
|
|
|
ShipListEntry {
|
|
|
ShipListEntry {
|
|
|
menu: SHIP_MENU_ID,
|
|
|
menu: SHIP_MENU_ID,
|
|
|
item: i as u32,
|
|
|
|
|
|
|
|
|
item: i.0 as u32,
|
|
|
flags: 0,
|
|
|
flags: 0,
|
|
|
name: utf8_to_utf16_array!(s.name, 0x11)
|
|
|
name: utf8_to_utf16_array!(s.name, 0x11)
|
|
|
}
|
|
|
}
|
|
@ -489,9 +492,9 @@ impl<EG: EntityGateway> CharacterServerState<EG> { |
|
|
return Err(CharacterError::InvalidMenuSelection(menuselect.menu, menuselect.item));
|
|
|
return Err(CharacterError::InvalidMenuSelection(menuselect.menu, menuselect.item));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
let ship = self.ships.get(menuselect.item as usize)
|
|
|
|
|
|
|
|
|
let ship = self.ships.get(&ServerId(menuselect.item as usize))
|
|
|
.ok_or(CharacterError::InvalidMenuSelection(menuselect.menu, menuselect.item))?;
|
|
|
.ok_or(CharacterError::InvalidMenuSelection(menuselect.menu, menuselect.item))?;
|
|
|
Ok(vec![SendCharacterPacket::RedirectClient(RedirectClient::new(u32::from_le_bytes(ship.ip), ship.port))])
|
|
|
|
|
|
|
|
|
Ok(vec![SendCharacterPacket::RedirectClient(RedirectClient::new(u32::from_le_bytes(ship.ip.octets()), ship.port))])
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@ -566,6 +569,32 @@ impl<EG: EntityGateway> ServerState for CharacterServerState<EG> { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
|
|
impl<EG: EntityGateway> InterserverActor for CharacterServerState<EG> {
|
|
|
|
|
|
type SendMessage = LoginMessage;
|
|
|
|
|
|
type RecvMessage = ShipMessage;
|
|
|
|
|
|
type Error = ();
|
|
|
|
|
|
|
|
|
|
|
|
async fn on_connect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
|
|
|
|
|
|
Vec::new()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async fn action(&mut self, id: ServerId, msg: Self::RecvMessage) -> Result<Vec<(ServerId, Self::SendMessage)>, Self::Error> {
|
|
|
|
|
|
match msg {
|
|
|
|
|
|
ShipMessage::Authenticate(auth_token) => {},
|
|
|
|
|
|
ShipMessage::NewShip(new_ship) => {
|
|
|
|
|
|
self.ships.insert(id, new_ship);
|
|
|
|
|
|
},
|
|
|
|
|
|
_ => {}
|
|
|
|
|
|
}
|
|
|
|
|
|
Ok(Vec::new())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async fn on_disconnect(&mut self, id: ServerId) -> Vec<(ServerId, Self::SendMessage)> {
|
|
|
|
|
|
Vec::new()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn new_character_from_preview(user: &UserAccountEntity, preview: &CharacterPreview) -> NewCharacterEntity {
|
|
|
fn new_character_from_preview(user: &UserAccountEntity, preview: &CharacterPreview) -> NewCharacterEntity {
|
|
|
let mut character = NewCharacterEntity::new(user.id);
|
|
|
let mut character = NewCharacterEntity::new(user.id);
|
|
|