55 Commits
179c9010a5
...
250be01fab
154 changed files with 4061 additions and 7560 deletions
-
16.drone.yml
-
2388Cargo.lock
-
68Cargo.toml
-
14src/bin/login.rs
-
52src/bin/main.rs
-
10src/bin/patch.rs
-
14src/bin/ship.rs
-
20src/client/Cargo.toml
-
27src/client/src/lib.rs
-
17src/drops/Cargo.toml
-
29src/drops/src/box_drop_table.rs
-
22src/drops/src/generic_armor.rs
-
18src/drops/src/generic_shield.rs
-
14src/drops/src/generic_unit.rs
-
18src/drops/src/generic_weapon.rs
-
94src/drops/src/lib.rs
-
28src/drops/src/rare_drop_table.rs
-
10src/drops/src/tech_table.rs
-
16src/drops/src/tool_table.rs
-
23src/entity/Cargo.toml
-
3src/entity/gateway/postgres/migrations/mod.rs
-
0src/entity/src/account.rs
-
4src/entity/src/character.rs
-
16src/entity/src/gateway/entitygateway.rs
-
26src/entity/src/gateway/inmemory.rs
-
0src/entity/src/gateway/mod.rs
-
0src/entity/src/gateway/postgres/migrations/V0001__initial.sql
-
0src/entity/src/gateway/postgres/migrations/V0002__equips.sql
-
0src/entity/src/gateway/postgres/migrations/V0003__item_notes.sql
-
0src/entity/src/gateway/postgres/migrations/V0004__meseta.sql
-
0src/entity/src/gateway/postgres/migrations/V0005__trade.sql
-
0src/entity/src/gateway/postgres/migrations/V0006__playtime.sql
-
0src/entity/src/gateway/postgres/migrations/V0007__player_keyconfig.sql
-
0src/entity/src/gateway/postgres/migrations/V0008__playtime_not_null.sql
-
0src/entity/src/gateway/postgres/migrations/V0009__no_player_keyconfig.sql
-
0src/entity/src/gateway/postgres/migrations/V0010__char_create_timestamp.sql
-
0src/entity/src/gateway/postgres/migrations/V0011__shared_bank.sql
-
14src/entity/src/gateway/postgres/migrations/V0012__room.sql
-
17src/entity/src/gateway/postgres/migrations/V0013__room2.sql
-
3src/entity/src/gateway/postgres/migrations/mod.rs
-
0src/entity/src/gateway/postgres/mod.rs
-
109src/entity/src/gateway/postgres/models.rs
-
117src/entity/src/gateway/postgres/postgres.rs
-
2src/entity/src/item/armor.rs
-
0src/entity/src/item/esweapon.rs
-
8src/entity/src/item/mag.rs
-
53src/entity/src/item/mod.rs
-
0src/entity/src/item/shield.rs
-
0src/entity/src/item/tech.rs
-
0src/entity/src/item/tool.rs
-
0src/entity/src/item/unit.rs
-
2src/entity/src/item/weapon.rs
-
1src/entity/src/lib.rs
-
83src/entity/src/room.rs
-
31src/entity/src/team.rs
-
25src/items/Cargo.toml
-
180src/items/src/actions.rs
-
20src/items/src/apply_item.rs
-
30src/items/src/bank.rs
-
20src/items/src/floor.rs
-
20src/items/src/inventory.rs
-
0src/items/src/itemstateaction.rs
-
3src/items/src/lib.rs
-
26src/items/src/state.rs
-
94src/items/src/tasks.rs
-
38src/items/src/trade.rs
-
17src/lib.rs
-
12src/location/Cargo.toml
-
2src/location/src/lib.rs
-
3src/login/mod.rs
-
92src/login/models.rs
-
21src/login_server/Cargo.toml
-
59src/login_server/src/character.rs
-
2src/login_server/src/lib.rs
-
45src/login_server/src/login.rs
-
14src/maps/Cargo.toml
-
2src/maps/src/area.rs
-
37src/maps/src/enemy.rs
-
59src/maps/src/lib.rs
-
28src/maps/src/maps.rs
-
4src/maps/src/monster.rs
-
8src/maps/src/object.rs
-
150src/maps/src/room.rs
-
3src/maps/src/variant.rs
-
18src/networking/Cargo.toml
-
0src/networking/src/cipherkeys.rs
-
4src/networking/src/interserver.rs
-
1src/networking/src/lib.rs
-
6src/networking/src/mainloop/client.rs
-
20src/networking/src/mainloop/interserver.rs
-
0src/networking/src/mainloop/mod.rs
-
0src/networking/src/serverstate.rs
-
2src/patch/mod.rs
-
15src/patch_server/Cargo.toml
-
4src/patch_server/src/lib.rs
-
22src/pktbuilder/Cargo.toml
-
11src/pktbuilder/src/character.rs
-
11src/pktbuilder/src/lib.rs
-
15src/pktbuilder/src/lobby.rs
-
106src/pktbuilder/src/message.rs
2388
Cargo.lock
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,20 @@ |
|||
[package] |
|||
name = "client" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
|
|||
[dependencies] |
|||
entity = { workspace = true } |
|||
maps = { workspace = true } |
|||
networking = { workspace = true } |
|||
shops = { workspace = true } |
|||
items = { workspace = true } |
|||
|
|||
libpso = { workspace = true } |
|||
|
|||
async-std = { workspace = true } |
|||
futures = { workspace = true } |
|||
anyhow = { workspace = true } |
|||
thiserror = { workspace = true } |
|||
chrono = { workspace = true } |
@ -0,0 +1,17 @@ |
|||
[package] |
|||
name = "drops" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
|
|||
[dependencies] |
|||
entity = { workspace = true } |
|||
maps = { workspace = true } |
|||
stats = { workspace = true } |
|||
|
|||
rand = { workspace = true } |
|||
rand_chacha = { workspace = true } |
|||
serde = { workspace = true } |
|||
enum-utils = { workspace = true } |
|||
toml = { workspace = true } |
|||
chrono = { workspace = true } |
@ -1,14 +1,14 @@ |
|||
use std::collections::BTreeMap;
|
|||
use serde::{Serialize, Deserialize};
|
|||
use rand::{Rng};
|
|||
use rand::Rng;
|
|||
use rand::seq::IteratorRandom;
|
|||
|
|||
use crate::entity::item::unit::{UnitType, Unit, UnitModifier};
|
|||
use crate::ship::room::{Difficulty, Episode};
|
|||
use crate::ship::map::MapArea;
|
|||
use crate::entity::character::SectionID;
|
|||
use crate::ship::drops::{ItemDropType, load_data_file};
|
|||
use crate::ship::item_stats::{unit_stats, UnitStats};
|
|||
use entity::character::SectionID;
|
|||
use entity::item::unit::{UnitType, Unit, UnitModifier};
|
|||
use maps::room::{Difficulty, Episode};
|
|||
use maps::area::MapArea;
|
|||
use crate::{ItemDropType, load_data_file};
|
|||
use stats::items::{unit_stats, UnitStats};
|
|||
|
|||
|
|||
|
@ -1,20 +1,20 @@ |
|||
use std::collections::HashMap;
|
|||
use rand::Rng;
|
|||
use serde::{Serialize, Deserialize};
|
|||
use crate::entity::item::weapon::{Weapon, WeaponType};
|
|||
use crate::entity::item::armor::{Armor, ArmorType};
|
|||
use crate::entity::item::shield::{Shield, ShieldType};
|
|||
use crate::entity::item::unit::{Unit, UnitType};
|
|||
use crate::entity::item::tool::{Tool, ToolType};
|
|||
use crate::entity::item::mag::{Mag, MagType};
|
|||
use crate::entity::character::SectionID;
|
|||
use crate::ship::monster::MonsterType;
|
|||
use crate::ship::room::{Difficulty, Episode};
|
|||
use crate::ship::map::MapArea;
|
|||
use crate::ship::drops::{ItemDropType, load_data_file};
|
|||
use crate::ship::drops::generic_weapon::AttributeTable;
|
|||
use crate::ship::drops::generic_armor::GenericArmorTable;
|
|||
use crate::ship::drops::generic_shield::GenericShieldTable;
|
|||
use entity::item::weapon::{Weapon, WeaponType};
|
|||
use entity::item::armor::{Armor, ArmorType};
|
|||
use entity::item::shield::{Shield, ShieldType};
|
|||
use entity::item::unit::{Unit, UnitType};
|
|||
use entity::item::tool::{Tool, ToolType};
|
|||
use entity::item::mag::{Mag, MagType};
|
|||
use entity::character::SectionID;
|
|||
use maps::monster::MonsterType;
|
|||
use maps::room::{Difficulty, Episode};
|
|||
use maps::area::MapArea;
|
|||
use crate::{ItemDropType, load_data_file};
|
|||
use crate::generic_weapon::AttributeTable;
|
|||
use crate::generic_armor::GenericArmorTable;
|
|||
use crate::generic_shield::GenericShieldTable;
|
|||
|
|||
type ItemParseFn = Box<dyn Fn(&String) -> Option<RareDropItem>>;
|
|||
|
@ -1,14 +1,14 @@ |
|||
use std::collections::{BTreeMap};
|
|||
use std::collections::BTreeMap;
|
|||
use serde::{Serialize, Deserialize};
|
|||
use rand::{Rng};
|
|||
use rand::Rng;
|
|||
use rand::distributions::{WeightedIndex, Distribution};
|
|||
|
|||
use crate::entity::item::tool::{Tool, ToolType};
|
|||
use crate::ship::room::{Difficulty, Episode};
|
|||
use crate::ship::map::MapArea;
|
|||
use crate::entity::character::SectionID;
|
|||
use crate::ship::drops::{ItemDropType, load_data_file};
|
|||
use crate::ship::drops::tech_table::TechniqueTable;
|
|||
use entity::item::tool::{Tool, ToolType};
|
|||
use maps::room::{Difficulty, Episode};
|
|||
use maps::area::MapArea;
|
|||
use entity::character::SectionID;
|
|||
use crate::{ItemDropType, load_data_file};
|
|||
use crate::tech_table::TechniqueTable;
|
|||
|
|||
|
|||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, enum_utils::FromStr)]
|
@ -0,0 +1,23 @@ |
|||
[package] |
|||
name = "entity" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
[dependencies] |
|||
libpso = { workspace = true } |
|||
maps = { workspace = true } |
|||
chrono = { workspace = true } |
|||
anyhow = { workspace = true } |
|||
async-std = { workspace = true } |
|||
sqlx = { workspace = true } |
|||
thiserror = { workspace = true } |
|||
serde = { workspace = true } |
|||
async-trait = { workspace = true } |
|||
enum-utils = { workspace = true } |
|||
derive_more = { workspace = true } |
|||
refinery = { workspace = true } |
|||
lazy_static = { workspace = true } |
|||
futures = { workspace = true } |
|||
strum = { workspace = true } |
|||
strum_macros = { workspace = true } |
|||
toml = { workspace = true } |
@ -1,3 +0,0 @@ |
|||
use refinery::include_migration_mods;
|
|||
|
|||
include_migration_mods!("src/entity/gateway/postgres/migrations");
|
@ -0,0 +1,14 @@ |
|||
create table room ( |
|||
id serial primary key not null, |
|||
name varchar(32) not null, |
|||
section_id char not null, |
|||
mode char not null, |
|||
episode char not null, |
|||
difficulty char not null |
|||
); |
|||
|
|||
create table room_note ( |
|||
room integer references room (id) not null, |
|||
note jsonb not null, |
|||
created_at timestamptz default current_timestamp not null |
|||
); |
@ -0,0 +1,17 @@ |
|||
drop table room_note; |
|||
drop table room; |
|||
|
|||
create table room ( |
|||
id serial primary key not null, |
|||
name varchar(32) not null, |
|||
section_id "char" not null, |
|||
mode "char" not null, |
|||
episode "char" not null, |
|||
difficulty "char" not null |
|||
); |
|||
|
|||
create table room_note ( |
|||
room integer references room (id) not null, |
|||
note jsonb not null, |
|||
created_at timestamptz default current_timestamp not null |
|||
); |
@ -0,0 +1,3 @@ |
|||
use refinery::include_migration_mods;
|
|||
|
|||
include_migration_mods!("src/gateway/postgres/migrations");
|
@ -1,5 +1,5 @@ |
|||
use serde::{Serialize, Deserialize};
|
|||
use crate::entity::item::ItemEntityId;
|
|||
use crate::item::ItemEntityId;
|
|||
|
|||
#[derive(Debug, Copy, Clone)]
|
|||
pub enum ItemParseError {
|
@ -1,9 +1,9 @@ |
|||
use thiserror::Error;
|
|||
use std::collections::HashMap;
|
|||
use thiserror::Error;
|
|||
use serde::{Serialize, Deserialize};
|
|||
use crate::entity::item::tool::ToolType;
|
|||
use crate::entity::character::{CharacterClass, SectionID};
|
|||
use crate::entity::item::ItemEntityId;
|
|||
use crate::item::tool::ToolType;
|
|||
use crate::character::{CharacterClass, SectionID};
|
|||
use crate::item::ItemEntityId;
|
|||
use std::io::Read;
|
|||
|
|||
use std::cmp::Ordering::{Less, Greater, Equal};
|
@ -1,4 +1,4 @@ |
|||
use crate::entity::item::ItemEntityId;
|
|||
use crate::item::ItemEntityId;
|
|||
use serde::{Serialize, Deserialize};
|
|||
|
|||
#[derive(Debug, Copy, Clone)]
|
@ -0,0 +1,83 @@ |
|||
use serde::{Serialize, Deserialize};
|
|||
|
|||
|
|||
use crate::character::{CharacterEntityId, SectionID};
|
|||
use maps::room::{Episode, Difficulty};
|
|||
|
|||
|
|||
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
|||
pub struct RoomEntityId(pub u32);
|
|||
|
|||
|
|||
#[derive(Debug, Copy, Clone)]
|
|||
pub enum RoomEntityMode {
|
|||
Multi,
|
|||
Single,
|
|||
Challenge,
|
|||
Battle,
|
|||
}
|
|||
|
|||
impl From<u8> for RoomEntityMode {
|
|||
fn from(other: u8) -> RoomEntityMode {
|
|||
match other {
|
|||
0 => RoomEntityMode::Multi,
|
|||
1 => RoomEntityMode::Single,
|
|||
2 => RoomEntityMode::Challenge,
|
|||
3 => RoomEntityMode::Battle,
|
|||
_ => unreachable!()
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
impl From<RoomEntityMode> for u8 {
|
|||
fn from(other: RoomEntityMode) -> u8 {
|
|||
match other {
|
|||
RoomEntityMode::Multi => 0,
|
|||
RoomEntityMode::Single => 1,
|
|||
RoomEntityMode::Challenge => 2,
|
|||
RoomEntityMode::Battle => 3,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
|
|||
#[derive(Debug, Clone)]
|
|||
pub struct RoomEntity {
|
|||
pub id: RoomEntityId,
|
|||
pub name: String,
|
|||
pub section_id: SectionID,
|
|||
pub mode: RoomEntityMode,
|
|||
pub episode: Episode,
|
|||
pub difficulty: Difficulty,
|
|||
}
|
|||
|
|||
|
|||
|
|||
#[derive(Debug, Clone)]
|
|||
pub struct NewRoomEntity {
|
|||
pub name: String,
|
|||
pub section_id: SectionID,
|
|||
pub mode: RoomEntityMode,
|
|||
pub episode: Episode,
|
|||
pub difficulty: Difficulty,
|
|||
}
|
|||
|
|||
#[derive(Debug, Copy, Clone, Serialize)]
|
|||
pub enum RoomNote {
|
|||
Create {
|
|||
character_id: CharacterEntityId,
|
|||
},
|
|||
PlayerJoin {
|
|||
character_id: CharacterEntityId,
|
|||
},
|
|||
PlayerLeave {
|
|||
character_id: CharacterEntityId,
|
|||
},
|
|||
QuestStart {
|
|||
// quest id
|
|||
},
|
|||
QuestComplete {
|
|||
// quest id
|
|||
},
|
|||
|
|||
}
|
@ -0,0 +1,31 @@ |
|||
use serde::{Serialize, Deserialize};
|
|||
|
|||
use super::account::UserAccountId;
|
|||
|
|||
// [2022-10-23 00:11:18][elseware::common::mainloop::client][WARN] error RecvServerPacket::from_bytes: WrongPacketForServerType(490, [40, 0, 234, 1, 0, 0, 0, 0, 9, 0, 74, 0, 97, 0, 115, 0, 100, 0, 102, 0, 0, 0, 0, 0, 192, 52, 67, 3, 60, 159, 129, 0, 32, 64, 233, 10, 196, 156, 152, 0])
|
|||
// [2022-10-23 00:20:14][elseware::common::mainloop::client][WARN] error RecvServerPacket::from_bytes: WrongPacketForServerType(490, [40, 0, 234, 1, 0, 0, 0, 0, 9, 0, 74, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 97, 0, 0, 0, 152, 0])
|
|||
|
|||
|
|||
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
|||
pub struct TeamEntityId(pub u32);
|
|||
|
|||
pub struct NewTeamEntity {
|
|||
pub created_by: UserAccountId,
|
|||
pub name: String,
|
|||
}
|
|||
|
|||
|
|||
#[derive(Debug, Clone)]
|
|||
pub struct TeamEntity {
|
|||
pub id: TeamEntityId,
|
|||
pub owner: UserAccountId,
|
|||
pub name: String,
|
|||
|
|||
pub team_flag: [u8; 2048],
|
|||
}
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,25 @@ |
|||
[package] |
|||
name = "items" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
[dependencies] |
|||
entity = { workspace = true } |
|||
maps = { workspace = true } |
|||
shops = { workspace = true } |
|||
location = { workspace = true } |
|||
drops = { workspace = true } |
|||
|
|||
libpso = { workspace = true } |
|||
|
|||
enum-utils = { workspace = true } |
|||
derive_more = { workspace = true } |
|||
serde = { workspace = true } |
|||
rand = { workspace = true } |
|||
rand_chacha = { workspace = true } |
|||
async-recursion = { workspace = true } |
|||
async-std = { workspace = true } |
|||
async-trait = { workspace = true } |
|||
futures = { workspace = true } |
|||
anyhow = { workspace = true } |
|||
thiserror = { workspace = true } |
@ -1,18 +1,18 @@ |
|||
use std::cmp::Ordering;
|
|||
use libpso::character::character;
|
|||
use crate::ship::items::ClientItemId;
|
|||
use crate::entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, InventoryEntity, InventoryItemEntity, EquippedEntity};
|
|||
use crate::ClientItemId;
|
|||
use entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, InventoryEntity, InventoryItemEntity, EquippedEntity};
|
|||
use std::future::Future;
|
|||
use async_std::sync::{Arc, Mutex};
|
|||
|
|||
use crate::entity::character::CharacterEntityId;
|
|||
use crate::entity::item::tool::ToolType;
|
|||
use crate::entity::item::mag::Mag;
|
|||
use crate::entity::item::weapon::Weapon;
|
|||
use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem};
|
|||
use crate::ship::items::state::ItemStateError;
|
|||
use crate::ship::items::state::{IndividualItemDetail, StackedItemDetail, AddItemResult};
|
|||
use crate::ship::items::floor::{FloorItem, FloorItemDetail};
|
|||
use entity::character::CharacterEntityId;
|
|||
use entity::item::tool::ToolType;
|
|||
use entity::item::mag::Mag;
|
|||
use entity::item::weapon::Weapon;
|
|||
use shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem};
|
|||
use crate::state::ItemStateError;
|
|||
use crate::state::{IndividualItemDetail, StackedItemDetail, AddItemResult};
|
|||
use crate::floor::{FloorItem, FloorItemDetail};
|
|||
|
|||
#[derive(Clone, Debug)]
|
|||
pub enum InventoryItemDetail {
|
@ -0,0 +1,38 @@ |
|||
use crate::ClientItemId;
|
|||
|
|||
#[derive(Debug, Clone)]
|
|||
pub enum TradeItem {
|
|||
Individual(ClientItemId),
|
|||
Stacked(ClientItemId, usize),
|
|||
}
|
|||
|
|||
impl TradeItem {
|
|||
pub fn stacked(&self) -> Option<(ClientItemId, usize)> {
|
|||
match self {
|
|||
TradeItem::Stacked(item_id, amount) => Some((*item_id, *amount)),
|
|||
_ => None
|
|||
}
|
|||
}
|
|||
|
|||
pub fn stacked_mut(&mut self) -> Option<(ClientItemId, &mut usize)> {
|
|||
match self {
|
|||
TradeItem::Stacked(item_id, ref mut amount) => Some((*item_id, amount)),
|
|||
_ => None
|
|||
}
|
|||
}
|
|||
|
|||
pub fn item_id(&self) -> ClientItemId {
|
|||
match self {
|
|||
TradeItem::Individual(item_id) => *item_id,
|
|||
TradeItem::Stacked(item_id, _) => *item_id,
|
|||
}
|
|||
}
|
|||
|
|||
pub fn amount(&self) -> usize {
|
|||
match self {
|
|||
TradeItem::Individual(_) => 1,
|
|||
TradeItem::Stacked(_, amount) => *amount,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
@ -1,17 +0,0 @@ |
|||
#![allow(clippy::type_complexity)]
|
|||
#![allow(incomplete_features)]
|
|||
#![feature(inline_const)]
|
|||
#![feature(drain_filter)]
|
|||
#![feature(try_blocks)]
|
|||
#![feature(once_cell)]
|
|||
#![feature(test)]
|
|||
#![feature(error_generic_member_access)]
|
|||
#![feature(provide_any)]
|
|||
|
|||
extern crate test;
|
|||
|
|||
pub mod common;
|
|||
pub mod entity;
|
|||
pub mod patch;
|
|||
pub mod login;
|
|||
pub mod ship;
|
@ -0,0 +1,12 @@ |
|||
[package] |
|||
name = "location" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
[dependencies] |
|||
networking = { workspace = true } |
|||
|
|||
async-std = { workspace = true } |
|||
derive_more = { workspace = true } |
|||
futures= { workspace = true } |
|||
thiserror = { workspace = true } |
@ -1,3 +0,0 @@ |
|||
#[allow(clippy::module_inception)]
|
|||
pub mod login;
|
|||
pub mod character;
|
@ -1,92 +0,0 @@ |
|||
use std::time::SystemTime;
|
|||
use std::io::Write;
|
|||
//use diesel::sql_types::Timestamp;
|
|||
use diesel::{Insertable, Queryable, Identifiable, Associations, AsExpression, FromSqlRow};
|
|||
//use bcrypt::{DEFAULT_COST, hash};
|
|||
use diesel::pg::Pg;
|
|||
use diesel::sql_types;
|
|||
use diesel::deserialize::{self, FromSql};
|
|||
use diesel::serialize::{self, ToSql, Output, IsNull};
|
|||
use diesel::backend::Backend;
|
|||
|
|||
use libpso::character::settings;
|
|||
|
|||
use elseware::schema::*;
|
|||
|
|||
//const ELSEWHERE_COST: u32 = bcrypt::DEFAULT_COST;
|
|||
const ELSEWHERE_COST: u32 = 5;
|
|||
|
|||
#[derive(Debug, AsExpression, FromSqlRow)]
|
|||
#[sql_type="sql_types::Binary"]
|
|||
pub struct EUserSettings(pub settings::UserSettings);
|
|||
|
|||
impl std::ops::Deref for EUserSettings {
|
|||
type Target = settings::UserSettings;
|
|||
|
|||
fn deref(&self) -> &Self::Target {
|
|||
&self.0
|
|||
}
|
|||
}
|
|||
|
|||
#[derive(Queryable, Identifiable, Debug)]
|
|||
pub struct UserAccount {
|
|||
pub id: i32,
|
|||
pub username: String,
|
|||
pub password: String,
|
|||
pub guildcard: Option<i32>,
|
|||
pub team_id: Option<i32>,
|
|||
pub banned: bool,
|
|||
pub muted_until: SystemTime,
|
|||
pub created_at: SystemTime,
|
|||
}
|
|||
|
|||
#[derive(Insertable)]
|
|||
#[table_name="user_accounts"]
|
|||
pub struct NewUser {
|
|||
username: String,
|
|||
password: String,
|
|||
}
|
|||
|
|||
impl NewUser {
|
|||
pub fn new(username: String, password: String) -> NewUser {
|
|||
let crypt_password = bcrypt::hash(password, ELSEWHERE_COST).expect("could not hash password?");
|
|||
NewUser {
|
|||
username: username,
|
|||
password: crypt_password,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
#[derive(Queryable, Identifiable, Associations)]
|
|||
#[belongs_to(UserAccount, foreign_key="user_id")]
|
|||
#[table_name="user_settings"]
|
|||
pub struct UserSettings {
|
|||
pub id: i32,
|
|||
pub user_id: i32,
|
|||
//settings: Vec<u8>,
|
|||
pub settings: EUserSettings,
|
|||
}
|
|||
|
|||
#[derive(Insertable, Debug)]
|
|||
#[table_name="user_settings"]
|
|||
pub struct NewUserSettings {
|
|||
pub user_id: i32,
|
|||
pub settings: EUserSettings,
|
|||
}
|
|||
|
|||
impl ToSql<sql_types::Binary, Pg> for EUserSettings {
|
|||
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
|
|||
out.write_all(&self.0.as_bytes()[..])
|
|||
.map(|_| IsNull::No)
|
|||
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
|||
}
|
|||
}
|
|||
|
|||
impl FromSql<sql_types::Binary, Pg> for EUserSettings {
|
|||
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
|
|||
let bytes_vec: Vec<u8> = <Vec<u8> as FromSql<sql_types::Binary, Pg>>::from_sql(bytes)?;
|
|||
let mut static_bytes = [0u8; 0x1160];
|
|||
static_bytes[..0x1160].clone_from_slice(&bytes_vec);
|
|||
Ok(EUserSettings(settings::UserSettings::from_bytes(static_bytes)))
|
|||
}
|
|||
}
|
@ -0,0 +1,21 @@ |
|||
[package] |
|||
name = "login_server" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
[dependencies] |
|||
entity = { workspace = true } |
|||
networking = { workspace = true } |
|||
pktbuilder = { workspace = true } |
|||
stats = { workspace = true } |
|||
|
|||
libpso = { workspace = true } |
|||
|
|||
async-std = { workspace = true } |
|||
async-trait = { workspace = true } |
|||
anyhow = { workspace = true } |
|||
bcrypt = { workspace = true } |
|||
crc = { workspace = true } |
|||
thiserror = { workspace = true } |
|||
chrono = { workspace = true } |
|||
rand= { workspace = true } |
@ -0,0 +1,2 @@ |
|||
pub mod login;
|
|||
pub mod character;
|
@ -0,0 +1,14 @@ |
|||
[package] |
|||
name = "maps" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
[dependencies] |
|||
byteorder = { workspace = true } |
|||
serde = { workspace = true } |
|||
thiserror = { workspace = true } |
|||
rand = { workspace = true } |
|||
rand_chacha = { workspace = true } |
|||
toml = { workspace = true } |
|||
enum-utils = { workspace = true } |
|||
derive_more = { workspace = true } |
@ -0,0 +1,59 @@ |
|||
pub mod area;
|
|||
pub mod enemy;
|
|||
pub mod object;
|
|||
pub mod variant;
|
|||
pub mod maps;
|
|||
pub mod monster;
|
|||
pub mod room;
|
|||
|
|||
#[derive(Clone, Copy)]
|
|||
pub enum Holiday {
|
|||
None,
|
|||
Christmas,
|
|||
Valentines,
|
|||
Easter,
|
|||
Halloween,
|
|||
Sonic,
|
|||
NewYear,
|
|||
Summer,
|
|||
White,
|
|||
Wedding,
|
|||
Fall,
|
|||
Spring,
|
|||
Summer2,
|
|||
Spring2,
|
|||
}
|
|||
|
|||
|
|||
impl From<Holiday> for u32 {
|
|||
fn from(other: Holiday) -> u32 {
|
|||
u16::from(other) as u32
|
|||
}
|
|||
}
|
|||
|
|||
impl From<Holiday> for u16 {
|
|||
fn from(other: Holiday) -> u16 {
|
|||
u8::from(other) as u16
|
|||
}
|
|||
}
|
|||
|
|||
impl From<Holiday> for u8 {
|
|||
fn from(other: Holiday) -> u8 {
|
|||
match other {
|
|||
Holiday::None => 0,
|
|||
Holiday::Christmas => 1,
|
|||
Holiday::Valentines => 3,
|
|||
Holiday::Easter => 4,
|
|||
Holiday::Halloween => 5,
|
|||
Holiday::Sonic => 6,
|
|||
Holiday::NewYear => 7,
|
|||
Holiday::Summer => 8,
|
|||
Holiday::White => 9,
|
|||
Holiday::Wedding => 10,
|
|||
Holiday::Fall => 11,
|
|||
Holiday::Spring => 12,
|
|||
Holiday::Summer2 => 13,
|
|||
Holiday::Spring2 => 14,
|
|||
}
|
|||
}
|
|||
}
|
@ -1,13 +1,11 @@ |
|||
// TOOD: `pub(super) for most of these?`
|
|||
|
|||
use std::io::{Read};
|
|||
use std::io::Read;
|
|||
|
|||
use byteorder::{LittleEndian, ReadBytesExt};
|
|||
|
|||
use crate::ship::room::Episode;
|
|||
|
|||
// TODO: don't use *
|
|||
use crate::ship::map::*;
|
|||
use crate::room::Episode;
|
|||
use crate::area::MapArea;
|
|||
|
|||
|
|||
#[derive(Debug, Copy, Clone)]
|
@ -0,0 +1,150 @@ |
|||
#[derive(Debug, Copy, Clone, derive_more::Display)]
|
|||
pub enum Episode {
|
|||
#[display(fmt="ep1")]
|
|||
One,
|
|||
#[display(fmt="ep2")]
|
|||
Two,
|
|||
#[display(fmt="ep4")]
|
|||
Four,
|
|||
}
|
|||
|
|||
impl TryFrom<u8> for Episode {
|
|||
type Error = ();
|
|||
|
|||
fn try_from(value: u8) -> Result<Episode, ()> {
|
|||
match value {
|
|||
1 => Ok(Episode::One),
|
|||
2 => Ok(Episode::Two),
|
|||
3 => Ok(Episode::Four),
|
|||
_ => Err(())
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
impl From<Episode> for u8 {
|
|||
fn from(other: Episode) -> u8 {
|
|||
match other {
|
|||
Episode::One => 1,
|
|||
Episode::Two => 2,
|
|||
Episode::Four => 3,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
impl Episode {
|
|||
pub fn from_quest(value: u8) -> Option<Episode> {
|
|||
match value {
|
|||
0 => Some(Episode::One),
|
|||
1 => Some(Episode::Two),
|
|||
2 => Some(Episode::Four),
|
|||
_ => None,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, derive_more::Display)]
|
|||
pub enum Difficulty {
|
|||
Normal,
|
|||
Hard,
|
|||
VeryHard,
|
|||
Ultimate,
|
|||
}
|
|||
|
|||
impl TryFrom<u8> for Difficulty {
|
|||
type Error = ();
|
|||
|
|||
fn try_from(value: u8) -> Result<Difficulty, ()> {
|
|||
match value {
|
|||
0 => Ok(Difficulty::Normal),
|
|||
1 => Ok(Difficulty::Hard),
|
|||
2 => Ok(Difficulty::VeryHard),
|
|||
3 => Ok(Difficulty::Ultimate),
|
|||
_ => Err(())
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
impl From<Difficulty> for u8 {
|
|||
fn from(other: Difficulty) -> u8 {
|
|||
match other {
|
|||
Difficulty::Normal => 0,
|
|||
Difficulty::Hard => 1,
|
|||
Difficulty::VeryHard => 2,
|
|||
Difficulty::Ultimate => 3,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
#[derive(Debug, Copy, Clone)]
|
|||
pub enum PlayerMode {
|
|||
Single,
|
|||
Multi,
|
|||
}
|
|||
|
|||
impl PlayerMode {
|
|||
pub fn value(&self) -> u8 {
|
|||
match self {
|
|||
PlayerMode::Single => 1,
|
|||
PlayerMode::Multi => 0,
|
|||
}
|
|||
}
|
|||
}
|
|||
|
|||
#[derive(Debug, Copy, Clone, derive_more::Display)]
|
|||
pub enum RoomMode {
|
|||
#[display(fmt="single")]
|
|||
Single {
|
|||
episode: Episode,
|
|||
difficulty: Difficulty,
|
|||
},
|
|||
#[display(fmt="multi")]
|
|||
Multi {
|
|||
episode: Episode,
|
|||
difficulty: Difficulty,
|
|||
},
|
|||
#[display(fmt="challenge")]
|
|||
Challenge {
|
|||
episode: Episode,
|
|||
},
|
|||
#[display(fmt="battle")]
|
|||
Battle {
|
|||
episode: Episode,
|
|||
difficulty: Difficulty,
|
|||
}
|
|||
}
|
|||
|
|||
|
|||
impl RoomMode {
|
|||
pub fn difficulty(&self) -> Difficulty {
|
|||
match self {
|
|||
RoomMode::Single {difficulty, ..} => *difficulty,
|
|||
RoomMode::Multi {difficulty, ..} => *difficulty,
|
|||
RoomMode::Battle {difficulty, ..} => *difficulty,
|
|||
RoomMode::Challenge {..} => Difficulty::Normal,
|
|||
}
|
|||
}
|
|||
|
|||
pub fn episode(&self) -> Episode {
|
|||
match self {
|
|||
RoomMode::Single {episode, ..} => *episode,
|
|||
RoomMode::Multi {episode, ..} => *episode,
|
|||
RoomMode::Battle {episode, ..} => *episode,
|
|||
RoomMode::Challenge {episode, ..} => *episode,
|
|||
}
|
|||
}
|
|||
|
|||
pub fn battle(&self) -> bool {
|
|||
matches!(self, RoomMode::Battle {..})
|
|||
}
|
|||
|
|||
pub fn challenge(&self) -> bool {
|
|||
matches!(self, RoomMode::Challenge {..})
|
|||
}
|
|||
|
|||
pub fn player_mode(&self) -> PlayerMode {
|
|||
match self {
|
|||
RoomMode::Single {..} => PlayerMode::Single,
|
|||
_ => PlayerMode::Multi,
|
|||
}
|
|||
}
|
|||
}
|
@ -0,0 +1,18 @@ |
|||
[package] |
|||
name = "networking" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
|
|||
[dependencies] |
|||
entity = { workspace = true } |
|||
|
|||
libpso = { workspace = true } |
|||
|
|||
async-std = { workspace = true } |
|||
async-trait = { workspace = true } |
|||
futures = { workspace = true } |
|||
log = { workspace = true } |
|||
serde = { workspace = true } |
|||
serde_json = { workspace = true } |
|||
derive_more = { workspace = true } |
@ -1,7 +1,6 @@ |
|||
pub mod cipherkeys;
|
|||
pub mod serverstate;
|
|||
pub mod mainloop;
|
|||
pub mod leveltable;
|
|||
pub mod interserver;
|
|||
|
|||
// https://www.reddit.com/r/rust/comments/33xhhu/how_to_create_an_array_of_structs_that_havent/
|
@ -1,2 +0,0 @@ |
|||
#[allow(clippy::module_inception)]
|
|||
pub mod patch;
|
@ -0,0 +1,15 @@ |
|||
[package] |
|||
name = "patch_server" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
[dependencies] |
|||
networking = { workspace = true } |
|||
|
|||
libpso = { workspace = true } |
|||
|
|||
async-trait = { workspace = true } |
|||
rand = { workspace = true } |
|||
crc = { workspace = true } |
|||
ron = { workspace = true } |
|||
serde = { workspace = true } |
@ -0,0 +1,22 @@ |
|||
[package] |
|||
name = "pktbuilder" |
|||
version = "0.1.0" |
|||
edition = "2021" |
|||
|
|||
[dependencies] |
|||
quests = { workspace = true } |
|||
stats = { workspace = true } |
|||
location = { workspace = true } |
|||
client = { workspace = true } |
|||
items = { workspace = true } |
|||
networking = { workspace = true } |
|||
maps = { workspace = true } |
|||
room = { workspace = true } |
|||
shops = { workspace = true } |
|||
entity = { workspace = true } |
|||
|
|||
libpso = { workspace = true } |
|||
|
|||
anyhow = { workspace = true } |
|||
futures = { workspace = true } |
|||
thiserror = { workspace = true } |
@ -1,10 +1,9 @@ |
|||
use libpso::character::character;
|
|||
use crate::common::leveltable::CharacterStats;
|
|||
use crate::entity::character::CharacterEntity;
|
|||
//use crate::ship::items::{CharacterInventory, CharacterBank};
|
|||
use crate::ship::items::bank::BankState;
|
|||
use crate::ship::items::inventory::InventoryState;
|
|||
use crate::entity::item::Meseta;
|
|||
use stats::leveltable::CharacterStats;
|
|||
use entity::character::CharacterEntity;
|
|||
use items::bank::BankState;
|
|||
use items::inventory::InventoryState;
|
|||
use entity::item::Meseta;
|
|||
|
|||
|
|||
#[derive(Default)]
|
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue