mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-02-12 19:31:07 +00:00
Restructure repository
* Move /common/src to /src * Move services to net.psforever package * Move /pslogin to /server
This commit is contained in:
parent
89a30ae6f6
commit
f4fd78fc5d
958 changed files with 527 additions and 725 deletions
69
server/src/main/resources/db/migration/V001__Init.sql
Normal file
69
server/src/main/resources/db/migration/V001__Init.sql
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
CREATE TABLE IF NOT EXISTS "accounts" (
|
||||
"id" SERIAL PRIMARY KEY NOT NULL,
|
||||
"username" VARCHAR(64) NOT NULL UNIQUE,
|
||||
"passhash" VARCHAR(64) NOT NULL,
|
||||
"created" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_modified" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"inactive" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"gm" BOOLEAN NOT NULL DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "characters" (
|
||||
"id" SERIAL PRIMARY KEY NOT NULL,
|
||||
"name" VARCHAR(64) NOT NULL,
|
||||
"account_id" INT NOT NULL REFERENCES accounts (id),
|
||||
"faction_id" INT NOT NULL,
|
||||
"gender_id" INT NOT NULL,
|
||||
"head_id" INT NOT NULL,
|
||||
"voice_id" INT NOT NULL,
|
||||
"created" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_login" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"last_modified" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"deleted" BOOLEAN NOT NULL DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "logins" (
|
||||
"id" SERIAL PRIMARY KEY NOT NULL,
|
||||
"account_id" INT NOT NULL REFERENCES accounts (id),
|
||||
"login_time" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"ip_address" VARCHAR(32) NOT NULL,
|
||||
"canonical_hostname" VARCHAR(132) NOT NULL,
|
||||
"hostname" VARCHAR(132) NOT NULL,
|
||||
"port" INT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "loadouts" (
|
||||
"id" SERIAL PRIMARY KEY NOT NULL,
|
||||
"characters_id" INT NOT NULL REFERENCES characters (id),
|
||||
"loadout_number" INT NOT NULL,
|
||||
"exosuit_id" INT NOT NULL,
|
||||
"name" VARCHAR(36) NOT NULL,
|
||||
"items" TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "lockers" (
|
||||
"id" SERIAL PRIMARY KEY NOT NULL,
|
||||
"characters_id" INT NOT NULL REFERENCES characters (id),
|
||||
"items" TEXT NOT NULL
|
||||
);
|
||||
|
||||
--These triggers update the last_modified timestamp column when a table is updated
|
||||
CREATE OR REPLACE FUNCTION fn_set_last_modified_timestamp()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.last_modified = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
DROP TRIGGER IF EXISTS trigger_accounts_set_last_modified on accounts;
|
||||
CREATE TRIGGER trigger_accounts_set_last_modified
|
||||
BEFORE UPDATE ON accounts
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE fn_set_last_modified_timestamp();
|
||||
|
||||
DROP TRIGGER IF EXISTS trigger_players_set_last_modified on characters;
|
||||
CREATE TRIGGER trigger_players_set_last_modified
|
||||
BEFORE UPDATE ON characters
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE fn_set_last_modified_timestamp();
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE IF NOT EXISTS "buildings" (
|
||||
local_id INT NOT NULL,
|
||||
zone_id INT NOT NULL,
|
||||
faction_id INT NOT NULL,
|
||||
PRIMARY KEY (local_id, zone_id)
|
||||
);
|
||||
29
server/src/main/resources/db/migration/V003__Avatar.sql
Normal file
29
server/src/main/resources/db/migration/V003__Avatar.sql
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
ALTER TABLE characters RENAME TO avatar;
|
||||
ALTER TABLE avatar RENAME CONSTRAINT characters_account_id_fkey TO avatar_account_id_fkey;
|
||||
ALTER TABLE accounts RENAME TO account;
|
||||
ALTER TABLE logins RENAME TO login;
|
||||
ALTER TABLE login RENAME CONSTRAINT logins_account_id_fkey TO login_account_id_fkey;
|
||||
ALTER TABLE loadouts RENAME TO loadout;
|
||||
ALTER TABLE loadout RENAME COLUMN characters_id TO avatar_id;
|
||||
ALTER TABLE loadout RENAME CONSTRAINT loadouts_characters_id_fkey TO loadout_avatar_id_fkey;
|
||||
ALTER TABLE lockers RENAME TO locker;
|
||||
ALTER TABLE locker RENAME COLUMN characters_id TO avatar_id;
|
||||
ALTER TABLE locker RENAME CONSTRAINT lockers_characters_id_fkey TO locker_avatar_id_fkey;
|
||||
ALTER TABLE buildings RENAME TO building;
|
||||
|
||||
ALTER TABLE avatar
|
||||
ADD COLUMN bep BIGINT NOT NULL DEFAULT 0,
|
||||
ADD COLUMN cep BIGINT NOT NULL DEFAULT 0,
|
||||
ADD COLUMN cosmetics INT;
|
||||
|
||||
CREATE TABLE certification (
|
||||
id INT NOT NULL,
|
||||
avatar_id INT NOT NULL REFERENCES avatar (id),
|
||||
PRIMARY KEY (id, avatar_id)
|
||||
);
|
||||
|
||||
CREATE TABLE implant (
|
||||
name TEXT NOT NULL,
|
||||
avatar_id INT NOT NULL REFERENCES avatar (id),
|
||||
PRIMARY KEY (name, avatar_id)
|
||||
);
|
||||
102
server/src/main/resources/overrides/game_objects0.adb.lst
Normal file
102
server/src/main/resources/overrides/game_objects0.adb.lst
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
add_property ace allowed false
|
||||
add_property ace equiptime 500
|
||||
add_property ace holstertime 500
|
||||
add_property ace_deployable allowed false
|
||||
add_property ace_deployable equiptime 500
|
||||
add_property ace_deployable holstertime 500
|
||||
add_property advanced_ace equiptime 750
|
||||
add_property advanced_ace holstertime 750
|
||||
add_property ams maxhealth 5000
|
||||
add_property ams jacking_duration 0 60 40 30
|
||||
add_property anniversary_gun equiptime 500
|
||||
add_property anniversary_gun holstertime 500
|
||||
add_property anniversary_guna equiptime 500
|
||||
add_property anniversary_guna holstertime 500
|
||||
add_property anniversary_gunb equiptime 500
|
||||
add_property anniversary_gunb holstertime 500
|
||||
add_property aphelion_flight requirement_award0 false
|
||||
add_property applicator equiptime 500
|
||||
add_property applicator firemode0_refiretime 500
|
||||
add_property applicator firemode1_refiretime 500
|
||||
add_property applicator holstertime 500
|
||||
add_property bank equiptime 500
|
||||
add_property bank holstertime 500
|
||||
add_property beamer equiptime 500
|
||||
add_property beamer holstertime 500
|
||||
add_property boomer_trigger equiptime 500
|
||||
add_property chainblade equiptime 250
|
||||
add_property chainblade holstertime 250
|
||||
add_property colossus_flight requirement_award0 false
|
||||
add_property command_detonater allowed false
|
||||
add_property command_detonater equiptime 500
|
||||
add_property command_detonater holstertime 500
|
||||
add_property cycler equiptime 600
|
||||
add_property cycler holstertime 600
|
||||
add_property cycler_v2 equiptime 600
|
||||
add_property cycler_v2 holstertime 600
|
||||
add_property cycler_v3 equiptime 600
|
||||
add_property cycler_v3 holstertime 600
|
||||
add_property cycler_v4 equiptime 600
|
||||
add_property cycler_v4 holstertime 600
|
||||
add_property flail_targeting_laser equiptime 500
|
||||
add_property flail_targeting_laser holstertime 500
|
||||
add_property flamethrower equiptime 1000
|
||||
add_property flamethrower holstertime 1000
|
||||
add_property flechette equiptime 600
|
||||
add_property flechette holstertime 600
|
||||
add_property forceblade equiptime 250
|
||||
add_property forceblade holstertime 250
|
||||
add_property galaxy_gunship allowed false
|
||||
add_property galaxy_gunship maxhealth 9500
|
||||
add_property gauss equiptime 600
|
||||
add_property gauss holstertime 600
|
||||
add_property ilc9 equiptime 500
|
||||
add_property ilc9 holstertime 500
|
||||
add_property isp equiptime 500
|
||||
add_property isp holstertime 500
|
||||
add_property katana equiptime 250
|
||||
add_property katana holstertime 250
|
||||
add_property lasher equiptime 750
|
||||
add_property lasher holstertime 750
|
||||
add_property lasher_projectile lash_delay 0.00
|
||||
add_property lasher_projectile_ap lash_delay 0.00
|
||||
add_property lasher_projectile_ap lasher_projectile_ap false
|
||||
add_property lasher_projectile_ap lasher_projectile true
|
||||
add_property maelstrom equiptime 1000
|
||||
add_property maelstrom holstertime 1000
|
||||
add_property magcutter equiptime 250
|
||||
add_property magcutter holstertime 250
|
||||
add_property medicalapplicator equiptime 500
|
||||
add_property medicalapplicator holstertime 500
|
||||
add_property medicalapplicator firemode0_refiretime 500
|
||||
add_property medicalapplicator firemode1_refiretime 500
|
||||
add_property mini_chaingun equiptime 750
|
||||
add_property mini_chaingun holstertime 750
|
||||
add_property nano_dispenser equiptime 750
|
||||
add_property nano_dispenser holstertime 750
|
||||
add_property pellet_gun equiptime 600
|
||||
add_property pellet_gun holstertime 600
|
||||
add_property peregrine_flight requirement_award0 false
|
||||
add_property pulsar equiptime 600
|
||||
add_property pulsar holstertime 600
|
||||
add_property punisher equiptime 600
|
||||
add_property punisher holstertime 600
|
||||
add_property r_shotgun equiptime 750
|
||||
add_property r_shotgun holstertime 750
|
||||
add_property remote_electronics_kit equiptime 500
|
||||
add_property remote_electronics_kit holstertime 500
|
||||
add_property repeater equiptime 500
|
||||
add_property repeater holstertime 500
|
||||
add_property six_shooter equiptime 500
|
||||
add_property six_shooter holstertime 500
|
||||
add_property spiker equiptime 500
|
||||
add_property spiker holstertime 500
|
||||
add_property super_staminakit allowed true
|
||||
add_property super_staminakit medkit_reuse_delay 300
|
||||
add_property super_staminakit nodrop false
|
||||
add_property super_staminakit requirement_award0 false
|
||||
add_property suppressor equiptime 600
|
||||
add_property suppressor holstertime 600
|
||||
add_property trek equiptime 500
|
||||
add_property trek holstertime 500
|
||||
add_property vulture requirement_award0 false
|
||||
54
server/src/main/resources/overrides/game_objects29.adb.lst
Normal file
54
server/src/main/resources/overrides/game_objects29.adb.lst
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
add_property ams requirement_certification0 false
|
||||
add_property apc requirement_certification0 false
|
||||
add_property aphelion allowed false
|
||||
add_property aphelion_flight allowed false
|
||||
add_property aphelion_gunner allowed false
|
||||
add_property aurora requirement_certification0 false
|
||||
add_property battlewagon requirement_certification0 false
|
||||
add_property colossus allowed false
|
||||
add_property colossus_flight allowed false
|
||||
add_property colossus_gunner allowed false
|
||||
add_property delivererv requirement_certification0 false
|
||||
add_property dropship allowed false
|
||||
add_property flail requirement_certification0 false
|
||||
add_property fury requirement_certification0 false
|
||||
add_property galaxy_gunship allowed false
|
||||
add_property liberator allowed false
|
||||
add_property lightgunship allowed false
|
||||
add_property lightning requirement_certification0 false
|
||||
add_property lodestar allowed false
|
||||
add_property magrider purchase_tech_plant false
|
||||
add_property magrider requirement_certification0 false
|
||||
add_property mediumtransport requirement_certification0 false
|
||||
add_property mosquito allowed false
|
||||
add_property nano_dispenser requirement_certification0 false
|
||||
add_property nchev_antiaircraft allowed false
|
||||
add_property order_terminal forsale_nchev_antiaircraft false
|
||||
add_property order_terminal forsale_trhev_antiaircraft false
|
||||
add_property order_terminal forsale_vshev_antiaircraft false
|
||||
add_property peregrine allowed false
|
||||
add_property peregrine_flight allowed false
|
||||
add_property peregrine_gunner allowed false
|
||||
add_property phantasm allowed false
|
||||
add_property prowler purchase_tech_plant false
|
||||
add_property prowler requirement_certification0 false
|
||||
add_property quadassault requirement_certification0 false
|
||||
add_property quadstealth requirement_certification0 false
|
||||
add_property skyguard requirement_certification0 false
|
||||
add_property skyguard requirement_certification1 false
|
||||
add_property threemanheavybuggy requirement_certification0 false
|
||||
add_property threemanheavybuggy requirement_certification1 false
|
||||
add_property thunderer requirement_certification0 false
|
||||
add_property trhev_antiaircraft allowed false
|
||||
add_property two_man_assault_buggy requirement_certification0 false
|
||||
add_property two_man_assault_buggy requirement_certification1 false
|
||||
add_property two_man_assault_buggy requirement_certification2 false
|
||||
add_property twomanheavybuggy requirement_certification0 false
|
||||
add_property twomanheavybuggy requirement_certification1 false
|
||||
add_property twomanhoverbuggy requirement_certification0 false
|
||||
add_property twomanhoverbuggy requirement_certification1 false
|
||||
add_property vanguard purchase_tech_plant false
|
||||
add_property vanguard requirement_certification0 false
|
||||
add_property vshev_antiaircraft allowed false
|
||||
add_property vulture allowed false
|
||||
add_property wasp allowed false
|
||||
61
server/src/main/resources/overrides/game_objects30.adb.lst
Normal file
61
server/src/main/resources/overrides/game_objects30.adb.lst
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
add_property air_vehicle_terminal forsale_dropship
|
||||
add_property air_vehicle_terminal forsale_galaxy_gunship
|
||||
add_property air_vehicle_terminal forsale_lodestar
|
||||
add_property apc allowed false
|
||||
add_property apc_nc allowed false
|
||||
add_property apc_tr allowed false
|
||||
add_property apc_vs allowed false
|
||||
add_property aphelion allowed false
|
||||
add_property aphelion_flight allowed false
|
||||
add_property aurora allowed false
|
||||
add_property battlewagon allowed false
|
||||
add_property colossus_flight allowed false
|
||||
add_property colossus_gunner allowed false
|
||||
add_property dropship requirement_certification0 false
|
||||
add_property flail allowed false
|
||||
add_property fury allowed false
|
||||
add_property galaxy_gunship requirement_certification0 false
|
||||
add_property hunterseeker requirement_certification0 false
|
||||
add_property lancer requirement_certification0 false
|
||||
add_property liberator requirement_certification0 false
|
||||
add_property liberator purchase_tech_plant false
|
||||
add_property lightgunship requirement_certification0 false
|
||||
add_property lightgunship purchase_tech_plant false
|
||||
add_property lightning allowed false
|
||||
add_property lodestar requirement_certification0 false
|
||||
add_property magrider allowed false
|
||||
add_property mediumtransport allowed false
|
||||
add_property mosquito requirement_certification0 false
|
||||
add_property mosquito requirement_certification1 false
|
||||
add_property nano_dispenser requirement_certification0 false
|
||||
add_property nchev_antiaircraft allowed false
|
||||
add_property order_terminal forsale_nchev_antiaircraft false
|
||||
add_property order_terminal forsale_trhev_antiaircraft false
|
||||
add_property order_terminal forsale_vshev_antiaircraft false
|
||||
add_property peregrine_flight allowed false
|
||||
add_property peregrine_gunner allowed false
|
||||
add_property phantasm requirement_certification0 false
|
||||
add_property phoenix requirement_certification0 false
|
||||
add_property prowler allowed false
|
||||
add_property quadassault allowed false
|
||||
add_property quadstealth allowed false
|
||||
add_property skyguard allowed false
|
||||
add_property striker requirement_certification0 false
|
||||
add_property switchblade allowed false
|
||||
add_property threemanheavybuggy allowed false
|
||||
add_property thunderer allowed false
|
||||
add_property trhev_antiaircraft allowed false
|
||||
add_property two_man_assault_buggy allowed false
|
||||
add_property twomanheavybuggy allowed false
|
||||
add_property twomanhoverbuggy allowed false
|
||||
add_property vanguard allowed false
|
||||
add_property vehicle_terminal_combined forsale_dropship
|
||||
add_property vehicle_terminal_combined forsale_galaxy_gunship
|
||||
add_property vehicle_terminal_combined forsale_lodestar
|
||||
add_property vshev_antiaircraft allowed false
|
||||
add_property vulture requirement_award0 false
|
||||
add_property vulture requirement_certification0 false
|
||||
add_property vulture purchase_tech_plant false
|
||||
add_property wasp purchase_tech_plant false
|
||||
add_property wasp requirement_certification0 false
|
||||
add_property wasp requirement_certification1 false
|
||||
134
server/src/main/resources/overrides/game_objects31.adb.lst
Normal file
134
server/src/main/resources/overrides/game_objects31.adb.lst
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
add_property ace requirement_certification0 false # combat_engineering
|
||||
add_property ace_deployable requirement_certification0 false # combat_engineering
|
||||
add_property advanced_ace firemode0_requirement_certification0 false # ce_defense
|
||||
add_property advanced_ace firemode0_requirement_certification1 false # ce_advanced
|
||||
add_property advanced_ace firemode1_requirement_certification0 false # ce_offense
|
||||
add_property advanced_ace firemode1_requirement_certification1 false # ce_advanced
|
||||
add_property advanced_ace firemode2_requirement_certification0 false # ce_offense
|
||||
add_property advanced_ace firemode2_requirement_certification1 false # ce_advanced
|
||||
add_property advanced_ace requirement_certification0 false # ce_defense
|
||||
add_property advanced_ace requirement_certification1 false # ce_offense
|
||||
add_property advanced_ace requirement_certification2 false # ce_advanced
|
||||
add_property air_vehicle_terminal forsale_dropship
|
||||
add_property air_vehicle_terminal forsale_galaxy_gunship
|
||||
add_property air_vehicle_terminal forsale_lodestar
|
||||
add_property ams requirement_certification0 false # ground_support
|
||||
add_property anniversary_gun requirement_certification0 false # medium_assault
|
||||
add_property ant requirement_certification0 false # vehicles
|
||||
add_property apc requirement_certification0 false # ground_transport
|
||||
add_property aphelion_flight requirement_award0 false # bfr_advanced
|
||||
add_property aphelion_laser requirement_certification0 false # bfr_ai_gunnery
|
||||
add_property aphelion_starfire requirement_certification0 false # bfr_aa_gunnery
|
||||
add_property applicator requirement_certification0 false # Medical
|
||||
add_property aurora requirement_certification0 false # ground_transport
|
||||
add_property bank requirement_certification0 false # Repair
|
||||
add_property beamer requirement_certification0 false # standard_assault
|
||||
add_property bfr_terminal requirement_certification0 false # bfr_basic
|
||||
add_property bolt_driver requirement_certification0 false # sniper
|
||||
add_property boomer_trigger requirement_certification0 false # combat_engineering
|
||||
add_property colossus_burster requirement_certification0 false # bfr_aa_gunnery
|
||||
add_property colossus_chaingun requirement_certification0 false # bfr_ai_gunnery
|
||||
add_property colossus_flight requirement_award0 false # bfr_advanced
|
||||
add_property cycler requirement_certification0 false # medium_assault
|
||||
add_property cycler_v2 requirement_certification0 false # medium_assault
|
||||
add_property cycler_v3 requirement_certification0 false # medium_assault
|
||||
add_property cycler_v4 requirement_certification0 false # medium_assault
|
||||
add_property delivererv requirement_certification0 false # ground_transport
|
||||
add_property dropship requirement_certification0 false # air_support
|
||||
add_property flail requirement_certification0 false # flail
|
||||
add_property flamethrower requirement_certification0 false # special_assault_2
|
||||
add_property flechette requirement_certification0 false # medium_assault
|
||||
add_property fury requirement_certification0 false # quad_all
|
||||
add_property galaxy_gunship requirement_certification0 false # gunship
|
||||
add_property gauss requirement_certification0 false # medium_assault
|
||||
add_property generic_bfr requirement_certification0 false # bfr_basic
|
||||
add_property heavy_sniper requirement_certification0 false # sniper
|
||||
add_property hunterseeker requirement_certification0 false # anti_vehicular
|
||||
add_property ilc9 requirement_certification0 false # standard_assault
|
||||
add_property isp requirement_certification0 false # standard_assault
|
||||
add_property katana requirement_award0 false # 2007_fan_faire
|
||||
add_property lancer requirement_certification0 false # anti_vehicular
|
||||
add_property lasher requirement_certification0 false # heavy_assault
|
||||
add_property liberator requirement_certification0 false # air_support
|
||||
add_property lightgunship requirement_certification0 false # air_cavalry_assault
|
||||
add_property lightning requirement_certification0 false # armored_assault1
|
||||
add_property lite_armor requirement_certification0 false # agile_armor
|
||||
add_property lodestar requirement_certification0 false # air_support
|
||||
add_property maelstrom requirement_certification0 false # heavy_assault
|
||||
add_property magrider requirement_certification0 false # armored_assault2
|
||||
add_property med_armor requirement_certification0 false # reinforced_armor
|
||||
add_property mediumtransport requirement_certification0 false # ground_transport
|
||||
add_property mini_chaingun requirement_certification0 false # heavy_assault
|
||||
add_property mosquito requirement_certification0 false # light_scout
|
||||
add_property mosquito requirement_certification1 false # air_cavalry_scout
|
||||
add_property nano_dispenser requirement_certification0 false # Repair
|
||||
add_property nchev_antiaircraft requirement_certification0 false # max_anti_aircraft
|
||||
add_property nchev_antiaircraft requirement_certification1 false # max_all
|
||||
add_property nchev_antipersonnel requirement_certification0 false # max_anti_personnel
|
||||
add_property nchev_antipersonnel requirement_certification1 false # max_all
|
||||
add_property nchev_antivehicular requirement_certification0 false # max_anti_vehicular
|
||||
add_property nchev_antivehicular requirement_certification1 false # max_all
|
||||
add_property oicw requirement_certification0 false # special_assault_2
|
||||
add_property pellet_gun requirement_certification0 false # standard_assault
|
||||
add_property peregrine_flight requirement_award0 false # bfr_advanced
|
||||
add_property peregrine_mechhammer requirement_certification0 false # bfr_ai_gunnery
|
||||
add_property peregrine_sparrow requirement_certification0 false # bfr_aa_gunnery
|
||||
add_property phantasm requirement_certification0 false # phantasm
|
||||
add_property phoenix requirement_certification0 false # anti_vehicular
|
||||
add_property prowler requirement_certification0 false # armored_assault2
|
||||
add_property pulsar requirement_certification0 false # medium_assault
|
||||
add_property punisher requirement_certification0 false # medium_assault
|
||||
add_property quadassault requirement_certification0 false # quad_all
|
||||
add_property quadstealth requirement_certification0 false # quad_all
|
||||
add_property r_shotgun requirement_certification0 false # heavy_assault
|
||||
add_property radiator requirement_certification0 false # special_assault
|
||||
add_property repeater requirement_certification0 false # standard_assault
|
||||
add_property rocklet requirement_certification0 false # special_assault
|
||||
add_property router requirement_certification0 false # ground_support
|
||||
add_property six_shooter requirement_certification0 false # standard_assault
|
||||
add_property skyguard requirement_certification0 false # assault_buggy
|
||||
add_property skyguard requirement_certification1 false # light_scout
|
||||
add_property spiker requirement_certification0 false # medium_assault
|
||||
add_property standard_issue_armor requirement_certification0 false # empire_issue
|
||||
add_property stealth_armor requirement_certification0 false # infiltration_suit
|
||||
add_property striker requirement_certification0 false # anti_vehicular
|
||||
add_property super_armorkit requirement_award0 false # xmas_spirit
|
||||
add_property super_medkit requirement_award0 false # xmas_snowman
|
||||
add_property super_staminakit requirement_award0 false # xmas_gingerman
|
||||
add_property suppressor requirement_certification0 false # standard_assault
|
||||
add_property switchblade requirement_certification0 false # switchblade
|
||||
add_property threemanheavybuggy requirement_certification0 false # assault_buggy
|
||||
add_property threemanheavybuggy requirement_certification1 false # light_scout
|
||||
add_property thumper requirement_certification0 false # special_assault
|
||||
add_property thunderer requirement_certification0 false # ground_transport
|
||||
add_property trek requirement_certification0 false # virus_hacking
|
||||
add_property trek requirement_certification1 false # electronics_expert
|
||||
add_property trhev_antiaircraft requirement_certification0 false # max_anti_aircraft
|
||||
add_property trhev_antiaircraft requirement_certification1 false # max_all
|
||||
add_property trhev_antipersonnel requirement_certification0 false # max_anti_personnel
|
||||
add_property trhev_antipersonnel requirement_certification1 false # max_all
|
||||
add_property trhev_antivehicular requirement_certification0 false # max_anti_vehicular
|
||||
add_property trhev_antivehicular requirement_certification1 false # max_all
|
||||
add_property two_man_assault_buggy requirement_certification0 false # light_scout
|
||||
add_property two_man_assault_buggy requirement_certification1 false # harasser
|
||||
add_property two_man_assault_buggy requirement_certification2 false # assault_buggy
|
||||
add_property twomanheavybuggy requirement_certification0 false # assault_buggy
|
||||
add_property twomanheavybuggy requirement_certification1 false # light_scout
|
||||
add_property twomanhoverbuggy requirement_certification0 false # assault_buggy
|
||||
add_property twomanhoverbuggy requirement_certification1 false # light_scout
|
||||
add_property twomanhoverbuggy_destroyed requirement_certification0 false # buggy_assault
|
||||
add_property vanguard requirement_certification0 false # armored_assault2
|
||||
add_property vehicle_terminal_combined forsale_dropship
|
||||
add_property vehicle_terminal_combined forsale_galaxy_gunship
|
||||
add_property vehicle_terminal_combined forsale_lodestar
|
||||
add_property vshev_antiaircraft requirement_certification0 false # max_anti_aircraft
|
||||
add_property vshev_antiaircraft requirement_certification1 false # max_all
|
||||
add_property vshev_antipersonnel requirement_certification0 false # max_anti_personnel
|
||||
add_property vshev_antipersonnel requirement_certification1 false # max_all
|
||||
add_property vshev_antivehicular requirement_certification0 false # max_anti_vehicular
|
||||
add_property vshev_antivehicular requirement_certification1 false # max_all
|
||||
add_property vulture requirement_award0 false # bomber_ace2
|
||||
add_property vulture requirement_certification0 false # air_support
|
||||
add_property wasp requirement_certification0 false # air_cavalry_interceptor
|
||||
add_property wasp requirement_certification1 false # air_cavalry_interceptor
|
||||
add_property winchester requirement_certification0 false # standard_assault
|
||||
80
server/src/main/resources/overrides/game_objects32.adb.lst
Normal file
80
server/src/main/resources/overrides/game_objects32.adb.lst
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
add_property ams requirement_certification0 false
|
||||
add_property anniversary_gun requirement_certification0 false
|
||||
add_property apc allowed false
|
||||
add_property apc_nc allowed false
|
||||
add_property apc_tr allowed false
|
||||
add_property apc_vs allowed false
|
||||
add_property aphelion allowed false
|
||||
add_property aphelion_flight allowed false
|
||||
add_property aphelion_gunner allowed false
|
||||
add_property aurora allowed false
|
||||
add_property battlewagon allowed false
|
||||
add_property colossus allowed false
|
||||
add_property colossus_flight allowed false
|
||||
add_property colossus_gunner allowed false
|
||||
add_property cycler requirement_certification0 false
|
||||
add_property delivererv allowed false
|
||||
add_property dropship requirement_certification0 false
|
||||
add_property flail allowed false
|
||||
add_property flechette requirement_certification0 false
|
||||
add_property fury allowed false
|
||||
add_property galaxy_gunship allowed false
|
||||
add_property gauss requirement_certification0 false
|
||||
add_property heavy_armor allowed false
|
||||
add_property hunterseeker requirement_certification0 false
|
||||
add_property lancer requirement_certification0 false
|
||||
add_property lasher requirement_certification0 false
|
||||
add_property liberator allowed false
|
||||
add_property lightgunship allowed false
|
||||
add_property lightning allowed false
|
||||
add_property lodestar allowed false
|
||||
add_property magrider allowed false
|
||||
add_property mediumtransport allowed false
|
||||
add_property mini_chaingun requirement_certification0 false
|
||||
add_property mosquito allowed false
|
||||
add_property nano_dispenser requirement_certification0 false
|
||||
add_property nchev allowed false
|
||||
add_property nchev_antiaircraft allowed false
|
||||
add_property nchev_antipersonnel allowed false
|
||||
add_property nchev_antivehicular allowed false
|
||||
add_property order_terminal forsale_nchev_antiaircraft false
|
||||
add_property order_terminal forsale_nchev_antipersonnel false
|
||||
add_property order_terminal forsale_nchev_antivehicular false
|
||||
add_property order_terminal forsale_trhev_antiaircraft false
|
||||
add_property order_terminal forsale_trhev_antipersonnel false
|
||||
add_property order_terminal forsale_trhev_antivehicular false
|
||||
add_property order_terminal forsale_vshev_antiaircraft false
|
||||
add_property order_terminal forsale_vshev_antipersonnel false
|
||||
add_property order_terminal forsale_vshev_antivehicular false
|
||||
add_property peregrine allowed false
|
||||
add_property peregrine_flight allowed false
|
||||
add_property peregrine_gunner allowed false
|
||||
add_property phantasm purchase_tech_plant false
|
||||
add_property phantasm requirement_certification0 false
|
||||
add_property phoenix requirement_certification0 false
|
||||
add_property prowler allowed false
|
||||
add_property pulsar requirement_certification0 false
|
||||
add_property punisher requirement_certification0 false
|
||||
add_property quadassault allowed false
|
||||
add_property quadstealth allowed false
|
||||
add_property r_shotgun requirement_certification0 false
|
||||
add_property router requirement_certification0 false
|
||||
add_property skyguard allowed false
|
||||
add_property striker requirement_certification0 false
|
||||
add_property switchblade allowed false
|
||||
add_property threemanheavybuggy allowed false
|
||||
add_property thunderer allowed false
|
||||
add_property trhev allowed false
|
||||
add_property trhev_antiaircraft allowed false
|
||||
add_property trhev_antipersonnel allowed false
|
||||
add_property trhev_antivehicular allowed false
|
||||
add_property two_man_assault_buggy allowed false
|
||||
add_property twomanheavybuggy allowed false
|
||||
add_property twomanhoverbuggy allowed false
|
||||
add_property vanguard allowed false
|
||||
add_property vshev allowed false
|
||||
add_property vshev_antiaircraft allowed false
|
||||
add_property vshev_antipersonnel allowed false
|
||||
add_property vshev_antivehicular allowed false
|
||||
add_property vulture allowed false
|
||||
add_property wasp allowed false
|
||||
277
server/src/main/scala/net/psforever/server/Server.scala
Normal file
277
server/src/main/scala/net/psforever/server/Server.scala
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
package net.psforever.server
|
||||
|
||||
import java.net.InetAddress
|
||||
import java.nio.file.Paths
|
||||
import java.util.Locale
|
||||
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import akka.routing.RandomPool
|
||||
import akka.{actor => classic}
|
||||
import ch.qos.logback.classic.LoggerContext
|
||||
import ch.qos.logback.classic.joran.JoranConfigurator
|
||||
import io.sentry.Sentry
|
||||
import kamon.Kamon
|
||||
import net.psforever.actors.session.SessionActor
|
||||
import net.psforever.crypto.CryptoInterface
|
||||
import net.psforever.login.psadmin.PsAdminActor
|
||||
import net.psforever.login._
|
||||
import net.psforever.objects.Default
|
||||
import net.psforever.objects.guid.TaskResolver
|
||||
import net.psforever.objects.zones._
|
||||
import net.psforever.services.account.{AccountIntermediaryService, AccountPersistenceService}
|
||||
import net.psforever.services.chat.ChatService
|
||||
import net.psforever.services.galaxy.GalaxyService
|
||||
import net.psforever.services.properties.PropertyOverrideManager
|
||||
import net.psforever.services.teamwork.SquadService
|
||||
import net.psforever.services.{InterstellarClusterService, ServiceManager}
|
||||
import net.psforever.util.Config
|
||||
import net.psforever.zones.Zones
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.flywaydb.core.Flyway
|
||||
import org.fusesource.jansi.Ansi.Color._
|
||||
import org.fusesource.jansi.Ansi._
|
||||
import org.slf4j
|
||||
import scopt.OParser
|
||||
|
||||
object Server {
|
||||
private val logger = org.log4s.getLogger
|
||||
|
||||
case class CliConfig(
|
||||
command: String = "run",
|
||||
noAutoMigrate: Boolean = false,
|
||||
baselineOnMigrate: Boolean = false,
|
||||
bind: Option[String] = None
|
||||
)
|
||||
|
||||
def printBanner(): Unit = {
|
||||
println(ansi().fgBright(BLUE).a(""" ___ ________"""))
|
||||
println(ansi().fgBright(BLUE).a(""" / _ \/ __/ __/__ _______ _ _____ ____"""))
|
||||
println(ansi().fgBright(MAGENTA).a(""" / ___/\ \/ _// _ \/ __/ -_) |/ / -_) __/"""))
|
||||
println(ansi().fgBright(RED).a("""/_/ /___/_/ \___/_/ \__/|___/\__/_/""").reset())
|
||||
println(""" PSForever Server - PSForever Project""")
|
||||
println(""" http://psforever.net""")
|
||||
println()
|
||||
}
|
||||
|
||||
def systemInformation: String = {
|
||||
val processors = Runtime.getRuntime.availableProcessors()
|
||||
val maxMemory = FileUtils.byteCountToDisplaySize(Runtime.getRuntime.maxMemory())
|
||||
|
||||
s"""|~~~ System Information ~~~
|
||||
|SYS: ${System.getProperty("os.name")} (v. ${System.getProperty("os.version")}, ${System
|
||||
.getProperty("os.arch")})
|
||||
|CPU: Detected $processors available logical processor${if (processors != 1) "s" else ""}
|
||||
|MEM: $maxMemory available to the JVM (tune with -Xmx flag)
|
||||
|JVM: ${System.getProperty("java.vm.name")} (build ${System.getProperty("java.version")}), ${System.getProperty(
|
||||
"java.vendor"
|
||||
)} - ${System.getProperty("java.vendor.url")}
|
||||
""".stripMargin
|
||||
}
|
||||
|
||||
def run(args: CliConfig): Unit = {
|
||||
val bindAddress: InetAddress =
|
||||
args.bind match {
|
||||
case Some(address) => InetAddress.getByName(address) // address from first argument
|
||||
case None => InetAddress.getByName(Config.app.bind) // address from config
|
||||
}
|
||||
|
||||
if (Config.app.kamon.enable) {
|
||||
logger.info("Starting Kamon")
|
||||
Kamon.init()
|
||||
}
|
||||
|
||||
if (Config.app.sentry.enable) {
|
||||
logger.info(s"Enabling Sentry")
|
||||
Sentry.init(Config.app.sentry.dsn)
|
||||
}
|
||||
|
||||
/** Start up the main actor system. This "system" is the home for all actors running on this server */
|
||||
implicit val system = classic.ActorSystem("PsLogin")
|
||||
Default(system)
|
||||
|
||||
/** Create pipelines for the login and world servers
|
||||
*
|
||||
* The first node in the pipe is an Actor that handles the crypto for protecting packets.
|
||||
* After any crypto operations have been applied or unapplied, the packets are passed on to the next
|
||||
* actor in the chain. For an incoming packet, this is a player session handler. For an outgoing packet
|
||||
* this is the session router, which returns the packet to the sending host.
|
||||
*
|
||||
* See SessionRouter.scala for a diagram
|
||||
*/
|
||||
val loginTemplate = List(
|
||||
SessionPipeline("crypto-session-", classic.Props[CryptoSessionActor]()),
|
||||
SessionPipeline("packet-session-", classic.Props[PacketCodingActor]()),
|
||||
SessionPipeline("login-session-", classic.Props[LoginSessionActor]())
|
||||
)
|
||||
val worldTemplate = List(
|
||||
SessionPipeline("crypto-session-", classic.Props[CryptoSessionActor]()),
|
||||
SessionPipeline("packet-session-", classic.Props[PacketCodingActor]()),
|
||||
SessionPipeline("world-session-", classic.Props[SessionActor]())
|
||||
)
|
||||
|
||||
val netSim: Option[NetworkSimulatorParameters] = if (Config.app.developer.netSim.enable) {
|
||||
val params = NetworkSimulatorParameters(
|
||||
Config.app.developer.netSim.loss,
|
||||
Config.app.developer.netSim.delay.toMillis,
|
||||
Config.app.developer.netSim.reorderChance,
|
||||
Config.app.developer.netSim.reorderTime.toMillis
|
||||
)
|
||||
logger.warn("NetSim is active")
|
||||
logger.warn(params.toString)
|
||||
Some(params)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
val zones = Zones.zones ++ Seq(Zone.Nowhere)
|
||||
|
||||
system.spawn(ChatService(), ChatService.ChatServiceKey.id)
|
||||
system.spawn(InterstellarClusterService(zones), InterstellarClusterService.InterstellarClusterServiceKey.id)
|
||||
|
||||
val serviceManager = ServiceManager.boot
|
||||
serviceManager ! ServiceManager.Register(classic.Props[AccountIntermediaryService](), "accountIntermediary")
|
||||
serviceManager ! ServiceManager.Register(RandomPool(150).props(classic.Props[TaskResolver]()), "taskResolver")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[GalaxyService](), "galaxy")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[SquadService](), "squad")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[AccountPersistenceService](), "accountPersistence")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[PropertyOverrideManager](), "propertyOverrideManager")
|
||||
|
||||
val loginRouter = classic.Props(new SessionRouter("Login", loginTemplate))
|
||||
val worldRouter = classic.Props(new SessionRouter("World", worldTemplate))
|
||||
val loginListener = system.actorOf(
|
||||
classic.Props(new UdpListener(loginRouter, "login-session-router", bindAddress, Config.app.login.port, netSim)),
|
||||
"login-udp-endpoint"
|
||||
)
|
||||
val worldListener = system.actorOf(
|
||||
classic.Props(new UdpListener(worldRouter, "world-session-router", bindAddress, Config.app.world.port, netSim)),
|
||||
"world-udp-endpoint"
|
||||
)
|
||||
|
||||
val adminListener = system.actorOf(
|
||||
classic.Props(
|
||||
new TcpListener(
|
||||
classOf[PsAdminActor],
|
||||
"net.psforever.login.psadmin-client-",
|
||||
InetAddress.getByName(Config.app.admin.bind),
|
||||
Config.app.admin.port
|
||||
)
|
||||
),
|
||||
"net.psforever.login.psadmin-tcp-endpoint"
|
||||
)
|
||||
|
||||
logger.info(
|
||||
s"Login server is running on ${InetAddress.getByName(Config.app.public).getHostAddress}:${Config.app.login.port}"
|
||||
)
|
||||
|
||||
// Add our shutdown hook (this works for Control+C as well, but not in Cygwin)
|
||||
sys addShutdownHook {
|
||||
// TODO: clean up active sessions and close resources safely
|
||||
logger.info("Login server now shutting down...")
|
||||
}
|
||||
}
|
||||
|
||||
def flyway(args: CliConfig): Flyway = {
|
||||
Flyway
|
||||
.configure()
|
||||
.dataSource(Config.app.database.toJdbc, Config.app.database.username, Config.app.database.password)
|
||||
.baselineOnMigrate(args.baselineOnMigrate)
|
||||
.load()
|
||||
}
|
||||
|
||||
def migrate(args: CliConfig): Unit = {
|
||||
flyway(args).migrate()
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
Locale.setDefault(Locale.US); // to have floats with dots, not comma
|
||||
|
||||
printBanner()
|
||||
println(systemInformation)
|
||||
|
||||
val loggerConfigPath = Paths.get(Config.directory, "logback.xml").toAbsolutePath.toString
|
||||
val loggerContext = slf4j.LoggerFactory.getILoggerFactory.asInstanceOf[LoggerContext]
|
||||
val configurator = new JoranConfigurator()
|
||||
configurator.setContext(loggerContext)
|
||||
loggerContext.reset()
|
||||
configurator.doConfigure(loggerConfigPath)
|
||||
|
||||
Config.result match {
|
||||
case Left(failures) =>
|
||||
logger.error("Loading config failed")
|
||||
failures.toList.foreach { failure =>
|
||||
logger.error(failure.toString)
|
||||
}
|
||||
sys.exit(1)
|
||||
case Right(_) =>
|
||||
}
|
||||
|
||||
/** Initialize the PSCrypto native library
|
||||
*
|
||||
* PSCrypto provides PlanetSide specific crypto that is required to communicate with it.
|
||||
* It has to be distributed as a native library because there is no Scala version of the required
|
||||
* cryptographic primitives (MD5MAC). See https://github.com/psforever/PSCrypto for more information.
|
||||
*/
|
||||
try {
|
||||
CryptoInterface.initialize()
|
||||
} catch {
|
||||
case e: UnsatisfiedLinkError =>
|
||||
logger.error("Unable to initialize " + CryptoInterface.libName)
|
||||
logger.error(e)(
|
||||
"This means that your PSCrypto version is out of date. Get the latest version from the README" +
|
||||
" https://github.com/psforever/PSF-LoginServer#downloading-pscrypto"
|
||||
)
|
||||
sys.exit(1)
|
||||
case e: IllegalArgumentException =>
|
||||
logger.error("Unable to initialize " + CryptoInterface.libName)
|
||||
logger.error(e)(
|
||||
"This means that your PSCrypto version is out of date. Get the latest version from the README" +
|
||||
" https://github.com/psforever/PSF-LoginServer#downloading-pscrypto"
|
||||
)
|
||||
sys.exit(1)
|
||||
}
|
||||
|
||||
val builder = OParser.builder[CliConfig]
|
||||
|
||||
val parser = {
|
||||
import builder._
|
||||
OParser.sequence(
|
||||
programName("psforever-server"),
|
||||
opt[Unit]("no-auto-migrate")
|
||||
.action((_, c) => c.copy(noAutoMigrate = true))
|
||||
.text("Do not auto migrate database."),
|
||||
opt[Unit]("baseline-on-migrate")
|
||||
.action((_, c) => c.copy(baselineOnMigrate = true))
|
||||
.text("Automatically baseline existing databases."),
|
||||
cmd("run")
|
||||
.action((_, c) => c.copy(command = "run"))
|
||||
.text("Run server.")
|
||||
.children(
|
||||
opt[String]("bind")
|
||||
.action((x, c) => c.copy(bind = Some(x)))
|
||||
.text("Bind address")
|
||||
),
|
||||
cmd("migrate")
|
||||
.action((_, c) => c.copy(command = "migrate"))
|
||||
.text("Apply database migrations.")
|
||||
)
|
||||
}
|
||||
|
||||
OParser.parse(parser, args, CliConfig()) match {
|
||||
case Some(config) =>
|
||||
config.command match {
|
||||
case "run" =>
|
||||
if (config.noAutoMigrate) {
|
||||
flyway(config).validate()
|
||||
} else {
|
||||
migrate(config)
|
||||
}
|
||||
run(config)
|
||||
case "migrate" =>
|
||||
migrate(config)
|
||||
}
|
||||
case _ =>
|
||||
sys.exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
server/src/test/resources/logback-test.xml
Normal file
11
server/src/test/resources/logback-test.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>[%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="ERROR">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
21
server/src/test/resources/testconfig.ini
Normal file
21
server/src/test/resources/testconfig.ini
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# This is a comment
|
||||
[default]
|
||||
string = a string
|
||||
string_quoted = "a string"
|
||||
int = 31
|
||||
time = 1 second
|
||||
time2 = 100 milliseconds
|
||||
float = 0.1
|
||||
bool_true = yes
|
||||
bool_false = no
|
||||
enum_dog = Dog
|
||||
# missing
|
||||
|
||||
[bad]
|
||||
bad_int = not a number
|
||||
bad_time = 10
|
||||
bad_float = A
|
||||
bad_bool = dunno
|
||||
bad_int_range = -1
|
||||
bad_int_range2 = 3
|
||||
bad_enum = Tree
|
||||
48
server/src/test/scala/MDCTestProbe.scala
Normal file
48
server/src/test/scala/MDCTestProbe.scala
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package net.psforever.pslogin
|
||||
|
||||
import akka.actor.{ActorRef, MDCContextAware}
|
||||
import akka.testkit.TestProbe
|
||||
import net.psforever.login.HelloFriend
|
||||
import net.psforever.packet.{ControlPacket, GamePacket}
|
||||
|
||||
final case class MDCGamePacket(packet: GamePacket)
|
||||
|
||||
final case class MDCControlPacket(packet: ControlPacket)
|
||||
|
||||
class MDCTestProbe(probe: TestProbe) extends MDCContextAware {
|
||||
/*
|
||||
The way this test mediator works needs to be explained.
|
||||
|
||||
MDCContextAware objects initialize themselves in a chain of ActorRefs defined in the HelloFriend message.
|
||||
As the iterator is consumed, it produces a right-neighbor (r-neighbor) that is much further along the chain.
|
||||
The HelloFriend is passed to that r-neighbor and that is how subsequent neighbors are initialized and chained.
|
||||
|
||||
MDCContextAware objects consume and produce internal messages called MdcMsg that wrap around the payload.
|
||||
Normally inaccessible from the outside, the payload is unwrapped within the standard receive PartialFunction.
|
||||
By interacting with a TestProbe constructor param, information that would be concealed by MdcMsg can be polled.
|
||||
|
||||
The l-neighbor of the MDCContextAware is the system of the base.actor.base.ActorTest TestKit.
|
||||
The r-neighbor of the MDCContextAware is this MDCTestProbe and, indirectly, the TestProbe that was interjected.
|
||||
Pass l-input into the MDCContextAware itself.
|
||||
The r-output is a normal message that can be polled on that TestProbe.
|
||||
Pass r-input into this MDCTestProbe directly.
|
||||
The l-output is an MdcMsg that can be treated just as r-output, sending it to this Actor and polling the TestProbe.
|
||||
*/
|
||||
private var left: ActorRef = ActorRef.noSender
|
||||
|
||||
def receive: Receive = {
|
||||
case msg @ HelloFriend(_, _) =>
|
||||
left = sender()
|
||||
probe.ref ! msg
|
||||
|
||||
case MDCGamePacket(msg) =>
|
||||
left ! msg
|
||||
|
||||
case MDCControlPacket(msg) =>
|
||||
left ! msg
|
||||
|
||||
case msg =>
|
||||
left ! msg
|
||||
probe.ref ! msg
|
||||
}
|
||||
}
|
||||
918
server/src/test/scala/PacketCodingActorTest.scala
Normal file
918
server/src/test/scala/PacketCodingActorTest.scala
Normal file
File diff suppressed because one or more lines are too long
32
server/src/test/scala/actor/base/ActorTest.scala
Normal file
32
server/src/test/scala/actor/base/ActorTest.scala
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package actor.base
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.testkit.{ImplicitSender, TestKit}
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import org.scalatest.BeforeAndAfterAll
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.wordspec.AnyWordSpecLike
|
||||
import org.specs2.specification.Scope
|
||||
|
||||
abstract class ActorTest(sys: ActorSystem = ActorSystem("system", ConfigFactory.parseMap(ActorTest.LoggingConfig)))
|
||||
extends TestKit(sys)
|
||||
with Scope
|
||||
with ImplicitSender
|
||||
with AnyWordSpecLike
|
||||
with Matchers
|
||||
with BeforeAndAfterAll {
|
||||
override def afterAll(): Unit = {
|
||||
TestKit.shutdownActorSystem(system)
|
||||
}
|
||||
}
|
||||
|
||||
object ActorTest {
|
||||
import scala.jdk.CollectionConverters._
|
||||
private val LoggingConfig = Map(
|
||||
"akka.loggers" -> List("akka.testkit.TestEventListener").asJava,
|
||||
"akka.loglevel" -> "OFF",
|
||||
"akka.stdout-loglevel" -> "OFF",
|
||||
"akka.log-dead-letters" -> "OFF"
|
||||
).asJava
|
||||
}
|
||||
258
server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala
Normal file
258
server/src/test/scala/actor/objects/VehicleSpawnPadTest.scala
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package actor.objects
|
||||
|
||||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import akka.testkit.TestProbe
|
||||
import actor.base.ActorTest
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.objects.serverobject.structures.StructureType
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.{PlanetSideGUID, _}
|
||||
import net.psforever.services.RemoverActor
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class VehicleSpawnControl1Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"construct" in {
|
||||
val obj = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "mb_pad_creation")
|
||||
assert(obj.Actor != ActorRef.noSender)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl2Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"complete a vehicle order" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
|
||||
zone.VehicleEvents = probe.ref //zone events
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
vehicle.Seats(0).Occupant = player
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.PlayerSeatedInVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideStart])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
//if we move the vehicle away from the pad, we should receive a ResetSpawnPad message
|
||||
//that means that the first order has cleared and the spawn pad is now waiting for additional orders
|
||||
vehicle.Position = Vector3(12, 0, 0)
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ResetSpawnPad])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl3Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"block the second vehicle order until the first is completed" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
//we can recycle the vehicle and the player for each order
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
val player2 = Player(Avatar(0, "test2", player.Faction, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
player2.GUID = PlanetSideGUID(11)
|
||||
player2.Continent = zone.id
|
||||
player2.Spawn()
|
||||
|
||||
zone.VehicleEvents = probe.ref //zone events
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //first order
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player2, vehicle) //second order (vehicle shared)
|
||||
|
||||
assert(probe.receiveOne(1 seconds) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Queue, _) => true
|
||||
case _ => false
|
||||
})
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
vehicle.Seats(0).Occupant = player
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.PlayerSeatedInVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideStart])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
|
||||
//if we move the vehicle away from the pad, we should receive a second ConcealPlayer message
|
||||
//that means that the first order has cleared and the spawn pad is now working on the second order successfully
|
||||
player.VehicleSeated = None //since shared between orders, as necessary
|
||||
vehicle.Seats(0).Occupant = None
|
||||
vehicle.Position = Vector3(12, 0, 0)
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ResetSpawnPad])
|
||||
probe.expectMsgClass(3 seconds, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl4Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"clean up the vehicle if the driver-to-be is on the wrong continent" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe.ref
|
||||
player.Continent = "problem" //problem
|
||||
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
val msg = probe.receiveOne(1 minute)
|
||||
assert(
|
||||
msg match {
|
||||
case VehicleServiceMessage.Decon(RemoverActor.AddTask(v, z, _)) => (v == vehicle) && (z == zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
probe.expectNoMessage(5 seconds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl5Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"abandon a destroyed vehicle on the spawn pad (blocking)" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe.ref
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
vehicle.Health = 0 //problem
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl6Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"abandon a vehicle on the spawn pad if driver is unfit to drive (blocking)" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
zone.VehicleEvents = probe.ref
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
player.Die
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnControl7Test extends ActorTest {
|
||||
"VehicleSpawnControl" should {
|
||||
"abandon a vehicle on the spawn pad if driver is unfit to drive (blocking)" in {
|
||||
val (vehicle, player, pad, zone) = VehicleSpawnPadControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val probe = new TestProbe(system, "zone-events")
|
||||
player.ExoSuit = ExoSuitType.MAX
|
||||
|
||||
zone.VehicleEvents = probe.ref //zone events
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.LoadVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object VehicleSpawnPadControlTest {
|
||||
import net.psforever.objects.zones.ZoneMap
|
||||
private val map = new ZoneMap("test-map")
|
||||
|
||||
def SetUpAgents(
|
||||
faction: PlanetSideEmpire.Value
|
||||
)(implicit system: ActorSystem): (Vehicle, Player, VehicleSpawnPad, Zone) = {
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.vehicles.VehicleControl
|
||||
import net.psforever.objects.Tool
|
||||
import net.psforever.types.CharacterGender
|
||||
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool]
|
||||
val guid: NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5))
|
||||
guid.AddPool("test-pool", (0 to 5).toList)
|
||||
guid.register(vehicle, "test-pool")
|
||||
guid.register(weapon, "test-pool")
|
||||
guid.register(weapon.AmmoSlot.Box, "test-pool")
|
||||
val zone = new Zone("test-zone", map, 0) {
|
||||
override def SetupNumberPools(): Unit = {}
|
||||
}
|
||||
zone.GUID(guid)
|
||||
zone.actor = system.spawn(ZoneActor(zone), s"test-zone-${System.nanoTime()}")
|
||||
|
||||
// Hack: Wait for the Zone to finish booting, otherwise later tests will fail randomly due to race conditions
|
||||
// with actor probe setting
|
||||
// TODO(chord): Remove when Zone supports notification of booting being complete
|
||||
Thread.sleep(5000)
|
||||
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), s"vehicle-control-${System.nanoTime()}")
|
||||
|
||||
val pad = VehicleSpawnPad(GlobalDefinitions.mb_pad_creation)
|
||||
pad.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], pad), s"test-pad-${System.nanoTime()}")
|
||||
pad.Owner =
|
||||
new Building("Building", building_guid = 0, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building)
|
||||
pad.Owner.Faction = faction
|
||||
pad.Zone = zone
|
||||
guid.register(pad, "test-pool")
|
||||
val player = Player(Avatar(0, "test", faction, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
guid.register(player, "test-pool")
|
||||
player.Zone = zone
|
||||
player.Spawn()
|
||||
//note: pad and vehicle are both at Vector3(1,0,0) so they count as blocking
|
||||
pad.Position = Vector3(1, 0, 0)
|
||||
vehicle.Position = Vector3(1, 0, 0)
|
||||
(vehicle, player, pad, zone)
|
||||
}
|
||||
}
|
||||
674
server/src/test/scala/actor/service/AvatarServiceTest.scala
Normal file
674
server/src/test/scala/actor/service/AvatarServiceTest.scala
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package actor.service
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.routing.RandomPool
|
||||
import actor.base.ActorTest
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectClass, ObjectCreateMessageParent, PlacementData}
|
||||
import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstream}
|
||||
import net.psforever.types._
|
||||
import net.psforever.services.{RemoverActor, Service, ServiceManager}
|
||||
import net.psforever.services.avatar._
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
|
||||
class AvatarService1Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"construct" in {
|
||||
ServiceManager.boot(system)
|
||||
system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService2Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService3Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
ServiceManager.boot(system)
|
||||
"subscribe to a specific channel" in {
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! Service.Leave()
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService4Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! Service.LeaveAll()
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService5Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass an unhandled message" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! "hello"
|
||||
expectNoMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ArmorChangedTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ArmorChanged" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ArmorChanged(PlanetSideGUID(10), ExoSuitType.Reinforced, 0))
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ArmorChanged(ExoSuitType.Reinforced, 0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ConcealPlayerTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ConcealPlayer" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ConcealPlayer(PlanetSideGUID(10)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ConcealPlayer()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EquipmentInHandTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service")
|
||||
val toolDef = GlobalDefinitions.beamer
|
||||
val tool = Tool(toolDef)
|
||||
tool.GUID = PlanetSideGUID(40)
|
||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(41)
|
||||
val pkt = ObjectCreateMessage(
|
||||
toolDef.ObjectId,
|
||||
tool.GUID,
|
||||
ObjectCreateMessageParent(PlanetSideGUID(11), 2),
|
||||
toolDef.Packet.ConstructorData(tool).get
|
||||
)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass EquipmentInHand" in {
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.EquipmentInHand(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool)
|
||||
)
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentInHand(pkt)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeployItemTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "deploy-item-test-service")
|
||||
val objDef = GlobalDefinitions.motionalarmsensor
|
||||
val obj = new SensorDeployable(objDef)
|
||||
obj.Position = Vector3(1, 2, 3)
|
||||
obj.Orientation = Vector3(4, 5, 6)
|
||||
obj.GUID = PlanetSideGUID(40)
|
||||
val pkt = ObjectCreateMessage(
|
||||
objDef.ObjectId,
|
||||
obj.GUID,
|
||||
objDef.Packet.ConstructorData(obj).get
|
||||
)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass DeployItem" in {
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.DeployItem(PlanetSideGUID(10), obj))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.DropItem(pkt)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DroptItemTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service")
|
||||
val toolDef = GlobalDefinitions.beamer
|
||||
val tool = Tool(toolDef)
|
||||
tool.Position = Vector3(1, 2, 3)
|
||||
tool.Orientation = Vector3(4, 5, 6)
|
||||
tool.GUID = PlanetSideGUID(40)
|
||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(41)
|
||||
val pkt = ObjectCreateMessage(
|
||||
toolDef.ObjectId,
|
||||
tool.GUID,
|
||||
DroppedItemData(
|
||||
PlacementData(tool.Position, tool.Orientation),
|
||||
toolDef.Packet.ConstructorData(tool).get
|
||||
)
|
||||
)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass DropItem" in {
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.DropItem(PlanetSideGUID(10), tool))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.DropItem(pkt)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LoadPlayerTest extends ActorTest {
|
||||
val obj = Player(Avatar(0, "TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
obj.GUID = PlanetSideGUID(10)
|
||||
obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(11)
|
||||
val c1data = obj.Definition.Packet.DetailedConstructorData(obj).get
|
||||
val pkt1 = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(10), c1data)
|
||||
val parent = ObjectCreateMessageParent(PlanetSideGUID(12), 0)
|
||||
obj.VehicleSeated = PlanetSideGUID(12)
|
||||
val c2data = obj.Definition.Packet.DetailedConstructorData(obj).get
|
||||
val pkt2 = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(10), parent, c2data)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass LoadPlayer" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
//no parent data
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.LoadPlayer(PlanetSideGUID(20), ObjectClass.avatar, PlanetSideGUID(10), c1data, None)
|
||||
)
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarResponse.LoadPlayer(pkt1)))
|
||||
//parent data
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.LoadPlayer(PlanetSideGUID(20), ObjectClass.avatar, PlanetSideGUID(10), c2data, Some(parent))
|
||||
)
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarResponse.LoadPlayer(pkt2)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectDeleteTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ObjectDelete" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(10), PlanetSideGUID(11)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(PlanetSideGUID(11), 0))
|
||||
)
|
||||
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(10), PlanetSideGUID(11), 55))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(PlanetSideGUID(11), 55))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectHeldTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ObjectHeld" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectHeld(PlanetSideGUID(10), 1))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectHeld(1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PutDownFDUTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass PutDownFDU" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PutDownFDU(PlanetSideGUID(10)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PutDownFDU(PlanetSideGUID(10)))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlanetsideAttributeTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass PlanetsideAttribute" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PlanetsideAttribute(5, 1200L)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerStateTest extends ActorTest {
|
||||
val msg = PlayerStateMessageUpstream(
|
||||
PlanetSideGUID(75),
|
||||
Vector3(3694.1094f, 2735.4531f, 90.84375f),
|
||||
Some(Vector3(4.375f, 2.59375f, 0.0f)),
|
||||
61.875f,
|
||||
351.5625f,
|
||||
0.0f,
|
||||
136,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
112,
|
||||
0
|
||||
)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass PlayerState" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.PlayerState(
|
||||
PlanetSideGUID(10),
|
||||
Vector3(3694.1094f, 2735.4531f, 90.84375f),
|
||||
Some(Vector3(4.375f, 2.59375f, 0.0f)),
|
||||
61.875f,
|
||||
351.5625f,
|
||||
0.0f,
|
||||
136,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
)
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.PlayerState(
|
||||
Vector3(3694.1094f, 2735.4531f, 90.84375f),
|
||||
Some(Vector3(4.375f, 2.59375f, 0.0f)),
|
||||
61.875f,
|
||||
351.5625f,
|
||||
0.0f,
|
||||
136,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PickupItemTest extends ActorTest {
|
||||
val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
val tool = Tool(GlobalDefinitions.beamer)
|
||||
tool.GUID = PlanetSideGUID(40)
|
||||
|
||||
"pass PickUpItem" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PickupItem(PlanetSideGUID(10), tool))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(tool.GUID, 0)))
|
||||
}
|
||||
}
|
||||
|
||||
class ReloadTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass Reload" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.Reload(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.Reload(PlanetSideGUID(40))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeAmmoTest extends ActorTest {
|
||||
val ammoDef = GlobalDefinitions.energy_cell
|
||||
val ammoBox = AmmoBox(ammoDef)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass ChangeAmmo" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.ChangeAmmo(
|
||||
PlanetSideGUID(10),
|
||||
PlanetSideGUID(40),
|
||||
0,
|
||||
PlanetSideGUID(40),
|
||||
ammoDef.ObjectId,
|
||||
PlanetSideGUID(41),
|
||||
ammoDef.Packet.ConstructorData(ammoBox).get
|
||||
)
|
||||
)
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ChangeAmmo(
|
||||
PlanetSideGUID(40),
|
||||
0,
|
||||
PlanetSideGUID(40),
|
||||
ammoDef.ObjectId,
|
||||
PlanetSideGUID(41),
|
||||
ammoDef.Packet.ConstructorData(ammoBox).get
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeFireModeTest extends ActorTest {
|
||||
val ammoDef = GlobalDefinitions.energy_cell
|
||||
val ammoBox = AmmoBox(ammoDef)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireMode" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireMode(PlanetSideGUID(10), PlanetSideGUID(40), 0))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireMode(PlanetSideGUID(40), 0))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeFireStateStartTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireState_Start" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Start(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ChangeFireState_Start(PlanetSideGUID(40))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeFireStateStopTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireState_Stop" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Stop(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ChangeFireState_Stop(PlanetSideGUID(40))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WeaponDryFireTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass WeaponDryFire" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.WeaponDryFire(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.WeaponDryFire(PlanetSideGUID(40)))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarStowEquipmentTest extends ActorTest {
|
||||
val tool = Tool(GlobalDefinitions.beamer)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass StowEquipment" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.StowEquipment(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool)
|
||||
)
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.StowEquipment(PlanetSideGUID(11), 2, tool)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Preparation for these three Release tests is involved.
|
||||
The ServiceManager must not only be set up correctly, but must be given a TaskResolver.
|
||||
The AvatarService is started and that starts CorpseRemovalActor, an essential part of this test.
|
||||
The CorpseRemovalActor needs that TaskResolver created by the ServiceManager;
|
||||
but, another independent TaskResolver will be needed for manual parts of the test.
|
||||
(The ServiceManager's TaskResolver can be "borrowed" but that requires writing code to intercept it.)
|
||||
The Zone needs to be set up and initialized properly with a ZoneActor.
|
||||
The ZoneActor builds the GUID Actor and the ZonePopulationActor.
|
||||
|
||||
ALL of these Actors will talk to each other.
|
||||
The lines of communication can short circuit if the next Actor does not have the correct information.
|
||||
Putting Actor startup in the main class, outside of the body of the test, helps.
|
||||
Frequent pauses to allow everything to sort their messages also helps.
|
||||
Even with all this work, the tests have a high chance of failure just due to being asynchronous.
|
||||
*/
|
||||
class AvatarReleaseTest extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]()), "taskResolver")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) }
|
||||
}
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
val taskResolver = system.actorOf(Props[TaskResolver](), "release-test-resolver")
|
||||
zone.actor = system.spawn(ZoneActor(zone), "release-test-zone")
|
||||
val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
obj.Continent = "test"
|
||||
obj.Release
|
||||
|
||||
"AvatarService" should {
|
||||
"pass Release" in {
|
||||
expectNoMessage(100 milliseconds) //spacer
|
||||
|
||||
service ! Service.Join("test")
|
||||
taskResolver ! GUIDTask.RegisterObjectTask(obj)(zone.GUID)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
zone.Population ! Zone.Corpse.Add(obj)
|
||||
expectNoMessage(200 milliseconds) //spacer
|
||||
|
||||
assert(zone.Corpses.size == 1)
|
||||
assert(obj.HasGUID)
|
||||
val guid = obj.GUID
|
||||
service ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second
|
||||
|
||||
val reply1 = receiveOne(200 milliseconds)
|
||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||
val reply1msg = reply1.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply1msg.channel == "/test/Avatar")
|
||||
assert(reply1msg.avatar_guid == guid)
|
||||
assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release])
|
||||
assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj)
|
||||
|
||||
val reply2 = receiveOne(2 seconds)
|
||||
assert(reply2.isInstanceOf[AvatarServiceResponse])
|
||||
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply2msg.channel.equals("/test/Avatar"))
|
||||
assert(reply2msg.avatar_guid == Service.defaultPlayerGUID)
|
||||
assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete])
|
||||
assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid)
|
||||
|
||||
expectNoMessage(1 seconds)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
assert(!obj.HasGUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarReleaseEarly1Test extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]()), "taskResolver")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) }
|
||||
}
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
val taskResolver = system.actorOf(Props[TaskResolver](), "release-test-resolver")
|
||||
zone.actor = system.spawn(ZoneActor(zone), "release-test-zone")
|
||||
val obj = Player(Avatar(0, "TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
obj.Continent = "test"
|
||||
obj.Release
|
||||
|
||||
"AvatarService" should {
|
||||
"pass Release" in {
|
||||
expectNoMessage(100 milliseconds) //spacer
|
||||
|
||||
service ! Service.Join("test")
|
||||
taskResolver ! GUIDTask.RegisterObjectTask(obj)(zone.GUID)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
zone.Population ! Zone.Corpse.Add(obj)
|
||||
expectNoMessage(200 milliseconds) //spacer
|
||||
|
||||
assert(zone.Corpses.size == 1)
|
||||
assert(obj.HasGUID)
|
||||
val guid = obj.GUID
|
||||
service ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
||||
|
||||
val reply1 = receiveOne(200 milliseconds)
|
||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||
val reply1msg = reply1.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply1msg.channel == "/test/Avatar")
|
||||
assert(reply1msg.avatar_guid == guid)
|
||||
assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release])
|
||||
assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj)
|
||||
|
||||
service ! AvatarServiceMessage.Corpse(RemoverActor.HurrySpecific(List(obj), zone)) //IMPORTANT: ONE ENTRY
|
||||
val reply2 = receiveOne(200 milliseconds)
|
||||
assert(reply2.isInstanceOf[AvatarServiceResponse])
|
||||
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply2msg.channel.equals("/test/Avatar"))
|
||||
assert(reply2msg.avatar_guid == Service.defaultPlayerGUID)
|
||||
assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete])
|
||||
assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid)
|
||||
|
||||
expectNoMessage(1 seconds)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
assert(!obj.HasGUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarReleaseEarly2Test extends ActorTest {
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(RandomPool(1).props(Props[TaskResolver]()), "taskResolver")
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) }
|
||||
}
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
val taskResolver = system.actorOf(Props[TaskResolver](), "release-test-resolver")
|
||||
zone.actor = system.spawn(ZoneActor(zone), "release-test-zone")
|
||||
val objAlt =
|
||||
Player(
|
||||
Avatar(0, "TestCharacter2", PlanetSideEmpire.NC, CharacterGender.Male, 1, CharacterVoice.Voice1)
|
||||
) //necessary clutter
|
||||
val obj = Player(Avatar(0, "TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, CharacterVoice.Voice1))
|
||||
obj.Continent = "test"
|
||||
obj.Release
|
||||
|
||||
"AvatarService" should {
|
||||
"pass Release" in {
|
||||
expectNoMessage(100 milliseconds) //spacer
|
||||
|
||||
service ! Service.Join("test")
|
||||
taskResolver ! GUIDTask.RegisterObjectTask(obj)(zone.GUID)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
zone.Population ! Zone.Corpse.Add(obj)
|
||||
expectNoMessage(200 milliseconds) //spacer
|
||||
|
||||
assert(zone.Corpses.size == 1)
|
||||
assert(obj.HasGUID)
|
||||
val guid = obj.GUID
|
||||
service ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
||||
|
||||
val reply1 = receiveOne(200 milliseconds)
|
||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||
val reply1msg = reply1.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply1msg.channel == "/test/Avatar")
|
||||
assert(reply1msg.avatar_guid == guid)
|
||||
assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release])
|
||||
assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj)
|
||||
|
||||
service ! AvatarServiceMessage.Corpse(
|
||||
RemoverActor.HurrySpecific(List(objAlt, obj), zone)
|
||||
) //IMPORTANT: TWO ENTRIES
|
||||
val reply2 = receiveOne(100 milliseconds)
|
||||
assert(reply2.isInstanceOf[AvatarServiceResponse])
|
||||
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply2msg.channel.equals("/test/Avatar"))
|
||||
assert(reply2msg.avatar_guid == Service.defaultPlayerGUID)
|
||||
assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete])
|
||||
assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid)
|
||||
|
||||
expectNoMessage(1 seconds)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
assert(!obj.HasGUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object AvatarServiceTest {
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
private val number = new AtomicInteger(1)
|
||||
|
||||
def TestName: String = {
|
||||
s"service${number.getAndIncrement()}"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue