use std::net::Ipv4Addr; use log::{info}; use networking::interserver::AuthToken; use elseware::login::login::LoginServerState; use elseware::login::character::CharacterServerState; use patch_server::{PatchServerState, generate_patch_tree, load_config, load_motd}; use elseware::ship::ship::ShipServerStateBuilder; use maps::Holiday; use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::character::NewCharacterEntity; use entity::item::{NewItemEntity, ItemDetail, InventoryItemEntity}; use entity::item; fn setup_logger() { let colors = fern::colors::ColoredLevelConfig::new() .error(fern::colors::Color::Red) .warn(fern::colors::Color::Yellow) .info(fern::colors::Color::Green) .debug(fern::colors::Color::White) .trace(fern::colors::Color::BrightBlack); let stdio = fern::Dispatch::new() .level(log::LevelFilter::Debug) .format(move |out, message, record| { out.finish(format_args!( "\x1B[{}m[{}][{}][{}] {}\x1B[0m", colors.get_color(&record.level()).to_fg_str(), chrono::Local::now().format("%Y-%m-%d %H:%M:%S"), record.target(), record.level(), message, )) }) .chain(std::io::stdout()); let fileout = fern::Dispatch::new() .level(log::LevelFilter::Trace) .chain(fern::log_file(format!("log/elseware-{}.log", chrono::Local::now().format("%Y-%m-%d_%H-%M-%S"))).unwrap()); fern::Dispatch::new() .chain(stdio) .chain(fileout) .apply().unwrap(); } fn main() { setup_logger(); async_std::task::block_on(async move { //let mut entity_gateway = PostgresGateway::new("localhost", "elsewhere", "elsewhere", ""); let mut entity_gateway = InMemoryGateway::default(); for i in 0..5 { let fake_user = NewUserAccountEntity { email: format!("fake{i}@email.com"), username: if i == 0 { "hi".to_string() } else { format!("hi{}", i+1) }, password: bcrypt::hash("qwer", 5).unwrap(), guildcard: i + 1, team_id: None, banned_until: None, muted_until: None, flags: 0, activated: true, }; let fake_user = entity_gateway.create_user(fake_user).await.unwrap(); entity_gateway.create_user_settings(NewUserSettingsEntity::new(fake_user.id)).await.unwrap(); let mut character = NewCharacterEntity::new(fake_user.id); character.name = format!("Test Char {}", i*2); let character = entity_gateway.create_character(character).await.unwrap(); entity_gateway.set_character_meseta(&character.id, item::Meseta(999999)).await.unwrap(); entity_gateway.set_bank_meseta(&character.id, &item::BankIdentifier::Character, item::Meseta(999999)).await.unwrap(); let mut character = NewCharacterEntity::new(fake_user.id); character.slot = 2; character.name = "ItemRefactor".into(); character.exp = 80000000; let character = entity_gateway.create_character(character).await.unwrap(); entity_gateway.set_character_meseta(&character.id, item::Meseta(999999)).await.unwrap(); entity_gateway.set_bank_meseta(&character.id, &item::BankIdentifier::Character, item::Meseta(999999)).await.unwrap(); for _ in 0..3 { entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::Vulcan, grind: 0, special: None, attrs: [None, None, None], tekked: true, } ), }).await.unwrap(); } for _ in 0..8 { entity_gateway.create_item( NewItemEntity { item: ItemDetail::Tool ( item::tool::Tool { tool: item::tool::ToolType::Monomate, } ), }).await.unwrap(); } let item0 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::Raygun, grind: 5, special: Some(item::weapon::WeaponSpecial::Hell), attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), None,], tekked: false, } ), }).await.unwrap(); let item1 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::Handgun, grind: 5, special: Some(item::weapon::WeaponSpecial::Charge), attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), None,], tekked: true, } ), }).await.unwrap(); let item2_w = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::Vjaya, grind: 5, special: Some(item::weapon::WeaponSpecial::Charge), attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), None,], tekked: true, } ), }).await.unwrap(); let item3 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::Vulcan, grind: 5, special: Some(item::weapon::WeaponSpecial::Charge), attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), None,], tekked: true, } ), }).await.unwrap(); let item4 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::DarkFlow, grind: 0, special: None, attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),], tekked: true, } ), }).await.unwrap(); let item5_m = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Mag(item::mag::Mag::baby_mag(0)), }).await.unwrap(); for _ in 0..10usize { let fed_tool = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Tool ( item::tool::Tool { tool: item::tool::ToolType::Monomate, } ), }).await.unwrap(); entity_gateway.feed_mag(&item5_m.id, &fed_tool.id).await.unwrap(); } entity_gateway.change_mag_owner(&item5_m.id, &character).await.unwrap(); let item6 = entity_gateway.create_item( item::NewItemEntity { item: ItemDetail::Tool ( item::tool::Tool { tool: item::tool::ToolType::CellOfMag502, } ), }).await.unwrap(); let cell = entity_gateway.create_item( item::NewItemEntity { item: ItemDetail::Tool ( item::tool::Tool { tool: item::tool::ToolType::CellOfMag502, } ), }).await.unwrap(); entity_gateway.use_mag_cell(&item5_m.id, &cell.id).await.unwrap(); let item6_1 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::ESWeapon( item::esweapon::ESWeapon::new(item::esweapon::ESWeaponType::Saber) ), }).await.unwrap(); let item7_a = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Armor( item::armor::Armor { armor: item::armor::ArmorType::Frame, dfp: 2, evp: 2, slots: 4, } ), } ).await.unwrap(); let item8_s = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Shield( item::shield::Shield { shield: item::shield::ShieldType::Barrier, dfp: 5, evp: 5, } ), } ).await.unwrap(); let item9_u0 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { unit: item::unit::UnitType::PriestMind, modifier: Some(item::unit::UnitModifier::PlusPlus), } ), } ).await.unwrap(); let item10_u1 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { unit: item::unit::UnitType::PriestMind, modifier: Some(item::unit::UnitModifier::Plus), } ), } ).await.unwrap(); let item11_u2 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { unit: item::unit::UnitType::PriestMind, modifier: Some(item::unit::UnitModifier::Minus), } ), } ).await.unwrap(); let item12_u3 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { unit: item::unit::UnitType::PriestMind, modifier: Some(item::unit::UnitModifier::MinusMinus), } ), } ).await.unwrap(); let item13 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Mag( item::mag::Mag::baby_mag(5) ), } ).await.unwrap(); let item14 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { weapon: item::weapon::WeaponType::Vulcan, grind: 5, special: Some(item::weapon::WeaponSpecial::Charge), attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),], tekked: true, } ), }).await.unwrap(); let monomates = futures::future::join_all((0..6).map(|_| { let mut entity_gateway = entity_gateway.clone(); async move { entity_gateway.create_item( NewItemEntity { item: ItemDetail::Tool ( item::tool::Tool { tool: item::tool::ToolType::Monomate, } ), }).await.unwrap() } })).await; let equipped = item::EquippedEntity { weapon: Some(item2_w.id), armor: Some(item7_a.id), shield: Some(item8_s.id), unit: [Some(item9_u0.id), Some(item10_u1.id), Some(item11_u2.id), Some(item12_u3.id)], mag: Some(item5_m.id), }; entity_gateway.set_character_equips(&character.id, &equipped).await.unwrap(); let inventory = item::InventoryEntity::new(vec![InventoryItemEntity::from(item0), item1.into(), item2_w.into(), item3.into(), item4.into(), item5_m.into(), item6.into(), item6_1.into(), item7_a.into(), item8_s.into(), item9_u0.into(), item10_u1.into(), item11_u2.into(), item12_u3.into(), item13.into(), item14.into(), monomates.into()]); entity_gateway.set_character_inventory(&character.id, &inventory).await.unwrap(); entity_gateway.set_character_bank(&character.id, &item::BankEntity::default(), &item::BankIdentifier::Character).await.unwrap(); } info!("[patch] starting server"); let patch_config = load_config(); let patch_motd = load_motd(); let (patch_file_tree, patch_file_lookup) = generate_patch_tree(patch_config.path.as_str()); let patch_state = PatchServerState::new(patch_file_tree, patch_file_lookup, patch_motd); let patch_loop = async_std::task::spawn(async move { networking::mainloop::run_server(patch_state, patch_config.port).await; }); info!("[auth] starting server"); let login_state = LoginServerState::new(entity_gateway.clone(), "127.0.0.1".parse().unwrap()); let login_loop = async_std::task::spawn(async move { networking::mainloop::run_server(login_state, elseware::login::login::LOGIN_PORT).await; }); info!("[character] starting server"); let char_state = CharacterServerState::new(entity_gateway.clone(), AuthToken("".into())); let sub_char_state = char_state.clone(); let character_loop = async_std::task::spawn(async move { networking::mainloop::run_server(sub_char_state, elseware::login::character::CHARACTER_PORT).await; }); let sub_char_state = char_state.clone(); let inter_character_loop = async_std::task::spawn(async move { networking::mainloop::run_interserver_listen(sub_char_state, elseware::login::login::COMMUNICATION_PORT).await; }); info!("[ship] starting servers"); let ship_state = ShipServerStateBuilder::default() .name("US/Sona-Nyl".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT) .event(Holiday::Halloween) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop1 = async_std::task::spawn(async move { networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop1 = async_std::task::spawn(async move { networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; }); let ship_state = ShipServerStateBuilder::default() .name("EU/Dylath-Leen".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT+2000) .event(Holiday::Christmas) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop2 = async_std::task::spawn(async move { networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+2000).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop2 = async_std::task::spawn(async move { networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; }); let ship_state = ShipServerStateBuilder::default() .name("JP/Thalarion".into()) .ip(Ipv4Addr::new(127,0,0,1)) .port(elseware::ship::ship::SHIP_PORT+3000) .gateway(entity_gateway.clone()) .build(); let sub_ship_state = ship_state.clone(); let ship_loop3 = async_std::task::spawn(async move { networking::mainloop::run_server(sub_ship_state, elseware::ship::ship::SHIP_PORT+3000).await; }); let sub_ship_state = ship_state.clone(); let inter_ship_loop3 = async_std::task::spawn(async move { networking::mainloop::run_interserver_connect(sub_ship_state, std::net::Ipv4Addr::new(127, 0, 0, 1), elseware::login::login::COMMUNICATION_PORT).await; }); futures::future::join_all(vec![patch_loop, login_loop, character_loop, inter_character_loop, ship_loop1, ship_loop2, ship_loop3, inter_ship_loop1, inter_ship_loop2, inter_ship_loop3]).await; }); }