Compare commits

...

362 Commits

Author SHA1 Message Date
Martin Michelsen 2dc2f85b1a don't disconnect on duplicate EXP requests 2023-12-10 21:45:13 -08:00
Martin Michelsen 6ef5b59724 fix log level on ItemCreator 2023-12-10 21:31:51 -08:00
Martin Michelsen 2f32e8ab7d fix BB inventory desync when buying consumables from shop 2023-12-10 21:16:42 -08:00
Martin Michelsen 60c1aa71dc fix ToolV4 structure 2023-12-10 17:35:57 -08:00
Martin Michelsen a315f6d011 expand metadata comments in q058 2023-12-10 15:22:40 -08:00
Martin Michelsen a42594afd3 fix implicit signed conversion 2023-12-10 14:54:30 -08:00
Martin Michelsen 04445dabd0 fix default BB key config 2023-12-10 14:52:17 -08:00
Martin Michelsen 16cddd28b2 add quest script compiler 2023-12-10 14:24:30 -08:00
Martin Michelsen b53bde9046 expand comment on expand_rate 2023-12-10 09:16:59 -08:00
Martin Michelsen afd63ca1dd make ep2 quests have orange icon on non-BB versions 2023-12-09 19:21:31 -08:00
Martin Michelsen 8ae7696b51 fix $exit when v3 quests are loaded in ep3 games 2023-12-09 19:21:31 -08:00
Martin Michelsen 81d03738da enable $quest to load v3 quests on ep3 2023-12-09 19:10:54 -08:00
Martin Michelsen beb87b546f clean up map logging 2023-12-09 18:32:17 -08:00
Martin Michelsen 12572ed2d4 hide inventory/bank log messages if disabled in config.json 2023-12-09 10:56:58 -08:00
Martin Michelsen bb3d4ac847 disable $bank when character overlay is present 2023-12-09 10:38:48 -08:00
Martin Michelsen 0ded423c84 treat enemy type 0100 as NPC 2023-12-08 23:34:36 -08:00
Martin Michelsen 414ef0d825 don't send card search results if searcher is blocked 2023-12-08 23:34:32 -08:00
Martin Michelsen b54b32b461 reformat DAT constructor tables 2023-12-08 20:39:50 -08:00
Martin Michelsen 67e2428daa don't load Challenge map data on quest start 2023-12-08 20:22:04 -08:00
Martin Michelsen 8654555777 recreate map on challenge mode restart 2023-12-08 18:08:47 -08:00
Martin Michelsen 83166f1eff fix multi-area challenge enemy generation 2023-12-08 17:39:00 -08:00
Martin Michelsen fbf170ef12 fix slime enemy types 2023-12-08 17:38:42 -08:00
Martin Michelsen b7bc148e09 implement solo quest progression flags 2023-12-08 17:01:11 -08:00
Martin Michelsen 009a0fc93d fix Monest child_type 2023-12-08 10:02:36 -08:00
Martin Michelsen 5a98b48521 don't set floor if it's negative 2023-12-08 10:01:01 -08:00
Martin Michelsen bf17ec0943 add unknown enemy type 0118 2023-12-08 09:51:57 -08:00
Martin Michelsen e901f5e681 don't save licenses for replay sessions 2023-12-07 20:27:46 -08:00
Martin Michelsen 6136f8dfb3 implement $edit on v1/v2 2023-12-07 20:08:46 -08:00
Martin Michelsen 0c18656e03 update note about get_game_version 2023-12-07 17:05:26 -08:00
Martin Michelsen 317c9fd616 implement Simple Mail auto-reply when recipient is offline 2023-12-07 12:46:01 -08:00
Martin Michelsen 6d16f8095a factor ClientGameData into Client to reduce data duplication 2023-12-07 12:23:21 -08:00
Martin Michelsen 072ebe81bf add $savechar and $loadchar commands 2023-12-06 23:54:53 -08:00
Martin Michelsen 7db761f181 fix attribute upgrade in Gallon's Shop 2023-12-06 15:57:37 -08:00
Martin Michelsen 7211205e55 fix meseta and material import in $bbchar 2023-12-06 09:55:33 -08:00
Martin Michelsen 85d0bac5cb assign bank item IDs at game join time 2023-12-06 09:46:57 -08:00
Martin Michelsen 713327b0ae fix double language marker on BB 2023-12-05 23:31:16 -08:00
Martin Michelsen 0ce5210c22 add v4 ItemPT data 2023-12-05 23:31:16 -08:00
Martin Michelsen 4ccbb2f683 don't disconnect when no combinations apply 2023-12-05 23:31:16 -08:00
Martin Michelsen 3075370975 add $qcheck command 2023-12-05 23:31:16 -08:00
Matt Swift 9dfdbc624b Add fixed BB Gallon's Shop 2023-12-05 23:07:07 -08:00
Martin Michelsen 027956876d fix episode 3 tests 2023-12-04 22:40:07 -08:00
Martin Michelsen cd1cc43cb3 update to-do list 2023-12-04 22:40:07 -08:00
Martin Michelsen 77798e09be prevent player from joining game if a quest they don't have access to is in progress 2023-12-04 22:40:07 -08:00
Martin Michelsen da0ffea7e0 prevent player from joining game if a quest they don't have access to is in progress 2023-12-04 21:42:51 -08:00
Martin Michelsen 330dbecada rewrite $bbchar implementation 2023-12-04 19:38:42 -08:00
Martin Michelsen 2360beb77b sort bank contents before sending to client 2023-12-04 18:43:37 -08:00
Martin Michelsen 33bbb15bf0 fix stacked item bank deposit bug 2023-12-04 18:23:41 -08:00
Martin Michelsen c25569c688 implement shared bank 2023-12-04 16:59:03 -08:00
Martin Michelsen 01b83044dc cache loaded player files between sessions 2023-12-04 12:38:26 -08:00
Martin Michelsen e05dcb6e70 update rare enemy rates 2023-12-04 10:37:02 -08:00
Martin Michelsen 501a048af0 allow specifying minimum levels for difficulties 2023-12-03 23:35:38 -08:00
Martin Michelsen f605a21c1a add option to specify BB rare enemy rates 2023-12-03 21:44:56 -08:00
Martin Michelsen 8e1edbc34e update notes about DC prototypes 2023-12-03 21:44:56 -08:00
Martin Michelsen 83549fe8e4 update compatibility table 2023-12-03 16:59:05 -08:00
Martin Michelsen fbda7a2a48 fix GC NTE proxy behavior 2023-12-03 16:34:09 -08:00
Martin Michelsen b8d4ab589e update compatibility table 2023-12-03 00:06:32 -08:00
Martin Michelsen e49e159eee implement HDLC/PPP in IPStackSimulator 2023-12-03 00:06:32 -08:00
Martin Michelsen 0442f6e579 fix Ep3 card trade sequence 2023-12-02 18:24:07 -08:00
Martin Michelsen 3160d86eaa only use language from quest header if it's valid 2023-12-01 22:27:58 -08:00
Martin Michelsen 4cd82caa5f fix GC NTE episode number when creating games 2023-12-01 21:34:51 -08:00
Martin Michelsen d943364c29 use DC quest download semantics for GC NTE 2023-12-01 21:00:10 -08:00
Martin Michelsen cddd8007c7 fix 6x75 on GC NTE 2023-12-01 20:29:11 -08:00
Martin Michelsen 039786b2f8 handle GC NTE character data struct 2023-12-01 20:05:12 -08:00
Martin Michelsen 5de53391db disable rare mag evolution logic on v1/v2 2023-12-01 17:34:16 -08:00
Martin Michelsen 5f8e0bd6bd add XB voice chat command structs 2023-12-01 17:32:55 -08:00
Martin Michelsen 3e83669138 update to-do list 2023-12-01 17:32:45 -08:00
Martin Michelsen 5593dc0ecd add PSOBB connection instructions 2023-11-30 10:59:31 -08:00
Martin Michelsen 956e890ad6 use make_shared where appropriate 2023-11-30 10:24:27 -08:00
Martin Michelsen c833b575e4 fix item table reloading 2023-11-30 10:24:11 -08:00
Martin Michelsen 4b3be7eee3 add fallback for undecodable text in quest disassembler 2023-11-30 09:48:40 -08:00
Martin Michelsen f7b6f602cd update to-do list 2023-11-30 09:48:24 -08:00
Martin Michelsen 695f14e3fb implement 6xD8 subcommand 2023-11-30 09:48:12 -08:00
Martin Michelsen 77906b7a57 update example config 2023-11-29 22:51:02 -08:00
Martin Michelsen 14fc0996bd fix team reward keys on quests 2023-11-29 22:48:20 -08:00
Martin Michelsen 3743d0a156 implement quest unlock flags 2023-11-29 22:22:19 -08:00
Martin Michelsen 3d2d96eb7e fix BB bank withdraw conditions 2023-11-29 18:45:30 -08:00
Martin Michelsen ba8917e50d implement team item rewards 2023-11-29 18:28:54 -08:00
Martin Michelsen b09269eabc update to-do list 2023-11-29 17:19:48 -08:00
Martin Michelsen d1ce010d06 make user flag that allows cheating even if cheats are disabled 2023-11-29 17:19:37 -08:00
Martin Michelsen 1e3ca4111a add TODO item about F94D quest opcode 2023-11-29 16:45:02 -08:00
Martin Michelsen 6a052722c9 load V1 rare tables 2023-11-29 16:44:53 -08:00
Martin Michelsen acb9c656c5 implement 6xCB subcommand 2023-11-29 16:42:24 -08:00
Martin Michelsen f5ebf6fdcd fix comment in rare-table-v1.json 2023-11-29 12:55:36 -08:00
Martin Michelsen 9ea84d7101 implement most remaining BB team functions 2023-11-29 11:35:15 -08:00
Martin Michelsen 556360c993 implement choice search 2023-11-28 18:38:43 -08:00
Martin Michelsen 4008d7f4ff remove history/future sections from readme 2023-11-28 18:38:43 -08:00
Matt e47b72dd72 Add Chinese/Korean download quests for PCv2 2023-11-28 14:06:21 -08:00
Martin Michelsen 613d0c6d36 update windows build instructions 2023-11-27 22:54:42 -08:00
Martin Michelsen 2d8de65dd0 fix initial lobby position commands across NTE/proto boundary 2023-11-27 22:50:44 -08:00
Martin Michelsen 33ef130098 allow word select across NTE/proto boundary 2023-11-27 22:50:23 -08:00
Martin Michelsen 3370d9c940 allow symbol chats to cross 11/2000 version boundary 2023-11-27 22:09:38 -08:00
Martin Michelsen 2c24cce740 send 15EA commands upon request 2023-11-27 21:34:28 -08:00
Martin Michelsen 26685ab32c save team config when points are earned 2023-11-27 21:31:10 -08:00
Martin Michelsen 1a5e56c0b2 fix team metadata in lobbies 2023-11-27 21:30:59 -08:00
Martin Michelsen 8e2a58ccaa eliminate ServerBehavior::DATA_SERVER_BB 2023-11-27 21:30:41 -08:00
Martin Michelsen 5192b5f615 hide some unnecessary data from log output 2023-11-27 21:29:48 -08:00
Martin Michelsen 9e55cd228c fix quest opcode flags constants 2023-11-27 16:02:58 -08:00
Martin Michelsen 65417749b2 don't send text messages to 11/2000 clients 2023-11-27 15:58:56 -08:00
Martin Michelsen 9a0ce6c131 update compatibility table in readme 2023-11-27 14:41:10 -08:00
Martin Michelsen d86b41daab update quest disassembler for 11/2000 prototype 2023-11-27 14:40:59 -08:00
Martin Michelsen 0a522e6ac4 add support for 12/2000 DC prototype 2023-11-27 14:40:42 -08:00
Martin Michelsen f2c3d256f3 fix quest disassembler opcode flags 2023-11-27 11:49:24 -08:00
Martin Michelsen dfb1249efc add comment about 11/2000 symbol chat 2023-11-27 11:49:20 -08:00
Martin Michelsen 7feb11b6a7 fix notes in compatibility table 2023-11-27 00:32:12 -08:00
Martin Michelsen 20b66a7a58 improve support for 11/2000 prototype 2023-11-27 00:29:26 -08:00
Martin Michelsen 9b6a023d38 preserve original disp if client is v1 or v2 2023-11-26 22:37:26 -08:00
Martin Michelsen ea83935dc4 implement BB EXP requests properly 2023-11-26 16:21:09 -08:00
Martin Michelsen 654132b5d2 fix BB team chat 2023-11-26 16:18:51 -08:00
Martin Michelsen e484ad72e0 rewrite quest category menu system 2023-11-26 14:52:37 -08:00
Martin Michelsen 64ac199730 fix battle map reloading 2023-11-26 11:46:10 -08:00
Martin Michelsen f4e9b4c60a fix error message when CatchHandlerExceptions is off 2023-11-26 11:45:59 -08:00
Martin Michelsen a4039fa9cd update to-do list 2023-11-25 23:43:54 -08:00
Martin Michelsen 6af0527498 implement team points and member ranking 2023-11-25 23:12:09 -08:00
Martin Michelsen 1cd0092a41 use client's ignore_def value when it doesn't match server's 2023-11-25 22:15:08 -08:00
Martin Michelsen 62d4c65a7d fix help text formatting 2023-11-25 22:13:13 -08:00
Martin Michelsen 220259b093 fix BB quest map loading bug 2023-11-25 21:12:03 -08:00
Martin Michelsen 0f8d88bb58 remove debugging messages 2023-11-25 21:02:53 -08:00
Martin Michelsen 4a3716191b update compatibility notes in readme 2023-11-25 21:02:44 -08:00
Martin Michelsen 5c58c500c1 fix DCNTE smoke test 2023-11-25 19:37:28 -08:00
Martin Michelsen a3d677316a fix DC NTE game join sync commands 2023-11-25 19:35:09 -08:00
Martin Michelsen 0f45ced3e9 add DC NTE map variations 2023-11-25 19:23:25 -08:00
Martin Michelsen ccfdbf2faf use 6x1F instead of 6F to unlock DC NTE games 2023-11-25 16:53:05 -08:00
Martin Michelsen 9c403e9107 remove unneeded debug prints 2023-11-25 16:26:19 -08:00
Martin Michelsen 46c3a44b41 fix uninitialized memory bug in UTF16 encoder 2023-11-25 16:12:11 -08:00
Martin Michelsen bc82594a26 add debugging prints for failure that only happens in GH Actions 2023-11-25 15:54:36 -08:00
Martin Michelsen e3ce4edede fix 8-bit challenge rank encryption 2023-11-25 15:33:33 -08:00
Martin Michelsen 61c37d86c1 fix signedness issue on linux 2023-11-25 13:16:45 -08:00
Martin Michelsen ff12a9aaca fix AR code translator stub 2023-11-25 12:41:24 -08:00
Martin Michelsen b5dbf25254 fix bug that causes long char names to disappear on BB 2023-11-25 12:30:27 -08:00
Martin Michelsen 10e5dc4708 clear arrow color when changing lobbies 2023-11-25 12:30:27 -08:00
Martin Michelsen 1b499ab953 fix spacing in help message 2023-11-25 12:30:27 -08:00
Martin Michelsen 011eedb855 add extra languages on PC v2 2023-11-25 12:30:27 -08:00
Martin Michelsen 897cca83cf add ability to disassemble DC NTE quests 2023-11-25 12:30:27 -08:00
Martin Michelsen fe6e957c92 add DC and GC NTE smoke tests 2023-11-25 12:30:27 -08:00
Martin Michelsen de4cb26c34 refactor GameVersion and QuestScriptVersion into a single enum 2023-11-25 12:30:27 -08:00
Martin Michelsen 9097abf307 fix starting inventory on new BB chars 2023-11-25 12:30:27 -08:00
Matt 14a86610ed Add download quests for V1 and PC 2023-11-25 10:26:33 -08:00
Matt 9e34ce6f49 Add official download quests for DC 2023-11-24 17:56:37 -08:00
Matt 7f1846013d Add missing DC version of MU3 2023-11-24 14:03:19 -08:00
Martin Michelsen 05d6d495a5 work around Tethealla bug in proxy 2023-11-21 23:04:20 -08:00
Martin Michelsen 5991a5a894 rewrite unit generation logic to fix v2/bb behavior 2023-11-21 22:11:41 -08:00
Martin Michelsen b0c481ed62 fix xbox 64 command on schtserv 2023-11-21 20:27:25 -08:00
Martin Michelsen 3712574784 minor style adjustment 2023-11-21 17:09:31 -08:00
Martin Michelsen e738f7f089 update to-do list 2023-11-21 17:09:18 -08:00
Martin Michelsen 8eba207a6b add BFR1 BB key 2023-11-21 13:31:22 -08:00
Martin Michelsen 67ed70082c rewrite 6x6D bug comment 2023-11-21 11:51:06 -08:00
Martin Michelsen 35aa6fba01 fix area number for specialized box item drops 2023-11-21 11:38:24 -08:00
Martin Michelsen 267c2ca00b fix invalid tool class on v3/v4 2023-11-21 11:25:25 -08:00
Martin Michelsen 1d8ae0b4d9 use constructor tables from GC and BB client in map parsing 2023-11-20 23:43:40 -08:00
Martin Michelsen 30ad83fa67 fix incorrect team metadata command target 2023-11-20 17:13:10 -08:00
Martin Michelsen 11880ecc05 fix v2 challenge mode overlays 2023-11-20 17:12:58 -08:00
Martin Michelsen a62b7dad26 fix warning in Map.cc 2023-11-19 23:20:14 -08:00
Martin Michelsen f8280e5f97 fix 6xC6 format 2023-11-19 23:18:31 -08:00
Martin Michelsen c1bf5ebb43 completely reset item creator when a quest loads 2023-11-19 23:07:21 -08:00
Martin Michelsen d1866c9bbf fix Ep2 Sinow child entity handling 2023-11-19 23:06:53 -08:00
Martin Michelsen 42e927caa9 add basic quest map disassembler 2023-11-19 23:06:30 -08:00
Martin Michelsen cd4c06231f fix challenge overlay creation on non-BB versions 2023-11-19 21:42:37 -08:00
Martin Michelsen 4588a71e5a implement 6xD1 command for BB challenge mode 2023-11-19 21:41:51 -08:00
Martin Michelsen 9476a3fc27 show rare seed and variations at game join time if $debug is on 2023-11-19 16:02:01 -08:00
Martin Michelsen b03ccc7e3e fix bug that leaves units equipped after armor item is destroyed 2023-11-19 16:01:24 -08:00
Martin Michelsen bc4092fb75 clean up switch block in team command handler 2023-11-19 13:13:55 -08:00
Martin Michelsen 261cefc8b1 name the unknown grave field in PlayerRecords_Challenge 2023-11-19 13:13:37 -08:00
Martin Michelsen 34666ee220 add missing challenge mode restart commands 2023-11-19 12:38:34 -08:00
Martin Michelsen c918596850 update to-do list 2023-11-19 12:38:22 -08:00
Martin Michelsen 976610705a fix wrap item bug 2023-11-18 23:13:34 -08:00
Martin Michelsen 5758f8dba1 remove in-game enemy drop debug message 2023-11-18 23:13:34 -08:00
Martin Michelsen 8d83b941d0 add debug messages in tekker adjustment code 2023-11-18 23:13:34 -08:00
Martin Michelsen 7ab98f41da fix challenge overlays for non-leaders 2023-11-18 23:13:34 -08:00
Martin Michelsen 5499d29cc2 add AR code translator shell 2023-11-18 23:13:34 -08:00
Martin Michelsen dd5873266d update sub_version notes 2023-11-18 23:13:34 -08:00
Martin Michelsen c1e225847e initial implementation of BB teams (WIP) 2023-11-18 23:13:34 -08:00
Matt 99d1a3272a Add English versions of JP-only BB quests 2023-11-18 15:13:19 -08:00
Martin Michelsen d316d2e260 fix game menu entry flags on v1/v2 2023-11-16 23:37:33 -08:00
Martin Michelsen 2f99a3760a fix visual.version field 2023-11-16 23:27:24 -08:00
Martin Michelsen 6b1a3e615b fix UTF-16 decoding bug again 2023-11-16 23:22:51 -08:00
Martin Michelsen 132395a53a fix DC NTE lobby interactions 2023-11-16 23:22:26 -08:00
Martin Michelsen 9cbcd09be0 fix UTF-16 decoding bug 2023-11-16 21:02:00 -08:00
Martin Michelsen 35f48cbd8f fix default in 18EA struct 2023-11-16 21:01:42 -08:00
Martin Michelsen db6578d57c move color encoding functions to GVMEncoder header 2023-11-16 21:01:06 -08:00
Martin Michelsen 4a5ea63f4a update 6xAC notes 2023-11-16 15:44:00 -08:00
Martin Michelsen 27608d9c11 implement 6xE1 2023-11-16 15:43:53 -08:00
Martin Michelsen c84d4b134f add BB global EXP multiplier 2023-11-15 22:38:37 -08:00
Martin Michelsen 722010c0f7 add $save command 2023-11-15 22:38:36 -08:00
Martin Michelsen 82c651a3ad implement BB trade window 2023-11-15 22:38:36 -08:00
Martin Michelsen 5834a41cec update to-do list 2023-11-15 21:34:27 -08:00
Martin Michelsen f48b5ac8b2 update notes on 8A command 2023-11-15 20:57:09 -08:00
Martin Michelsen 1b29f20541 fix incorrect object lists in quest 2023-11-15 20:01:45 -08:00
Martin Michelsen b492a2fac6 handle rejected tekker results properly 2023-11-15 18:14:04 -08:00
Martin Michelsen c896c11f57 fix duplicate pick up disconnections on BB 2023-11-15 17:29:09 -08:00
Martin Michelsen 6aef245eab fix item ID inconsistencies between server and client due to shops and tekker in BB 2023-11-15 17:18:46 -08:00
Martin Michelsen 8ae6500fb5 add extra aliases for m&y in $item 2023-11-15 17:17:59 -08:00
Martin Michelsen 768bdb5b05 fix variance on specialized boxes 2023-11-15 16:02:31 -08:00
Martin Michelsen f997376819 fix equip slot check 2023-11-15 15:24:54 -08:00
Martin Michelsen 3d7b6837ec disable equip tracking in non-BB games 2023-11-15 14:41:13 -08:00
Martin Michelsen 533ee04443 fix join command queue bug 2023-11-15 13:33:34 -08:00
Martin Michelsen 6e1691d023 fix mag stat adjustments during level up 2023-11-15 12:47:24 -08:00
Martin Michelsen be6fd25190 implement proper equip/unequip tracking 2023-11-15 12:47:14 -08:00
Martin Michelsen ac57fb16a4 fix unit modifiers in $item command 2023-11-15 11:39:50 -08:00
Martin Michelsen 687a4515a2 fix bug that caused sorting inventory to delete extended tech levels 2023-11-15 11:34:53 -08:00
Martin Michelsen 0705b4d155 don't filter by episode at government counter 2023-11-15 00:03:21 -08:00
Martin Michelsen 2818b4ac2f clean up bit cast 2023-11-14 23:50:46 -08:00
Martin Michelsen ab5536d554 add more quest debugging commands 2023-11-14 23:27:40 -08:00
Martin Michelsen fbb053883b implement 6xDE command 2023-11-14 23:27:27 -08:00
Martin Michelsen d1161dd8e4 fix cheat mode check on proxy 2023-11-14 22:25:03 -08:00
Martin Michelsen 91b54b635d fix bug that caused boxes to never be empty 2023-11-14 21:52:38 -08:00
Martin Michelsen 2e89cfa8d6 use server's rt_index for enemy item drops 2023-11-14 21:52:38 -08:00
Martin Michelsen 62d484472f implement 6xE0 command 2023-11-14 21:52:38 -08:00
Martin Michelsen ba3016f89c filter non-download quests by episode 2023-11-14 21:52:38 -08:00
Martin Michelsen c5605c8685 fix some missing client ID bounds checks 2023-11-14 21:52:38 -08:00
Martin Michelsen 126e5944f4 refine 6x70 structure 2023-11-14 21:52:38 -08:00
Martin Michelsen 1531f4dad2 work around data race during game join 2023-11-14 21:52:38 -08:00
Martin Michelsen 82d0539c31 also blank name_color_checksum during $bbchar 2023-11-14 12:29:35 -08:00
Martin Michelsen 5c47385bee fix some $bbchar bugs 2023-11-14 12:25:19 -08:00
Martin Michelsen e3956a0a09 improve specialized box log messages 2023-11-14 12:24:59 -08:00
Martin Michelsen 6568ba7e32 unset x bit on everything in system/ 2023-11-13 22:18:22 -08:00
Martin Michelsen 4fe238a01a track specialized boxes server-side 2023-11-13 22:07:21 -08:00
Martin Michelsen 4b4627d3e5 fix material tracking bug 2023-11-13 22:06:49 -08:00
Martin Michelsen a1b457a5e6 make EXP computation match the client 2023-11-13 18:16:59 -08:00
Martin Michelsen 1ca0e928a4 rename area -> floor in most places 2023-11-13 17:25:16 -08:00
Martin Michelsen 8d4c9ca93a add Ep3 EU in handler-tables 2023-11-13 16:49:46 -08:00
Martin Michelsen 83b8f1a87c delete now-unused player data templates 2023-11-13 16:21:35 -08:00
Martin Michelsen 33a6e307e9 add support for v1 rare item tables 2023-11-13 16:18:20 -08:00
Martin Michelsen 08fbbd50ad fix various battle mode behaviors 2023-11-13 15:42:17 -08:00
Martin Michelsen c5f047dc0d don't check missing categories during quest indexing 2023-11-13 14:25:49 -08:00
Martin Michelsen d976452e00 update readme for new quest directory structure 2023-11-13 14:25:49 -08:00
Martin Michelsen cbe69c6ada fix pvr codepath in quest loading 2023-11-13 14:25:49 -08:00
Martin Michelsen 201676be5c fix REG32_SET_FIXED disassembly 2023-11-13 14:25:49 -08:00
Martin Michelsen 5e6a5355f5 fix load condition for non-BB clients 2023-11-13 14:00:59 -08:00
Martin Michelsen 18ddfa4ef4 use .psochar format for BB characters 2023-11-13 13:00:22 -08:00
Martin Michelsen f5bfd4a3c6 fix signed/unsigned comparison 2023-11-12 20:16:29 -08:00
Martin Michelsen 9c821b2988 organize quests directory by category 2023-11-12 16:30:03 -08:00
Martin Michelsen afba337575 clean up random enemy generation 2023-11-12 12:19:37 -08:00
Martin Michelsen 53451c2d45 add both Ep3 EU ports in config.json 2023-11-12 12:16:48 -08:00
Matt 884653d41c Fix Xbox symlink for q240 2023-11-12 12:14:47 -08:00
Matt 5304fff790 Fix incorrect names for Episode 2 Challenge J 2023-11-12 12:14:47 -08:00
Matt 4316afc137 Add Xbox login and lobby ports 2023-11-12 12:14:47 -08:00
Matt 616f8ad827 Add J versions of BB side story quests 2023-11-12 12:14:47 -08:00
Matt f0f9171acd Add various BB quests 2023-11-12 12:14:47 -08:00
Matt 049135bd2d test commit 2023-11-12 12:14:47 -08:00
Matt 4e68e6a48c Add J versions of Challenge/Battle 2023-11-12 00:26:00 -08:00
Matt 272e757315 Add various BB quests 2023-11-12 00:26:00 -08:00
Matt 768c07b99a test commit 2023-11-12 00:26:00 -08:00
Martin Michelsen 4de1495c31 fix categories on updated Ep3 maps 2023-11-12 00:12:32 -08:00
Martin Michelsen 7872fea6ab send rare enemy list again after loading a quest 2023-11-12 00:01:41 -08:00
Martin Michelsen d33709f4a2 make quests appear in the menu even if they don't exist in player's language 2023-11-12 00:01:41 -08:00
Martin Michelsen 43d7815165 fix some item-related debug messages 2023-11-12 00:01:41 -08:00
Martin Michelsen 3057c31d01 update notes on Ep3 EU 50Hz 2023-11-12 00:01:41 -08:00
Martin Michelsen cce42c4165 add $quest command for debugging 2023-11-12 00:01:41 -08:00
Martin Michelsen 3e735fcea4 implement BB challenge mode random enemy generation 2023-11-11 23:58:24 -08:00
Martin Michelsen 779d32d20f fix $matcount on v2 2023-11-11 22:32:10 -08:00
Martin Michelsen 1fa3d3a56d add other languages for Ep3 maps 2023-11-11 21:44:00 -08:00
Martin Michelsen b2a22522d2 unset x bit on ep3 maps 2023-11-11 21:39:49 -08:00
Martin Michelsen 4e93b2fc8b fix S-rank weapon name encoding/decoding 2023-11-11 15:45:59 -08:00
Martin Michelsen 90b7f0d0c0 add $ping command 2023-11-10 17:59:43 -08:00
Martin Michelsen a0f0230700 forbid rare enemies in challenge mode 2023-11-10 12:41:41 -08:00
Martin Michelsen a0505176ec get quest episode number from start function instead of header 2023-11-10 12:41:29 -08:00
Martin Michelsen 51ba23faa6 exempt solo-mode games from $debug client placement 2023-11-10 11:57:58 -08:00
Martin Michelsen d8e35b021f fix disconnect message when Quit Game is selected 2023-11-09 10:33:08 -08:00
Martin Michelsen a966696d9d fix used_chars_16 error message 2023-11-09 09:18:32 -08:00
Martin Michelsen 72d0047634 fix incorrect parray usage 2023-11-09 09:18:21 -08:00
Martin Michelsen cabd03a82e implement BB challenge param commands 2023-11-08 22:44:59 -08:00
Martin Michelsen 3ea65ccc75 fix missing 6x1B handler 2023-11-08 19:01:01 -08:00
Martin Michelsen 38c0d975cc fix missing 6xDC handler 2023-11-08 15:47:56 -08:00
Martin Michelsen 77799d1a37 add comment about 9F command timing 2023-11-08 15:47:43 -08:00
Martin Michelsen 7d0438f149 fix area_norm for Episode 4 2023-11-07 22:51:44 -08:00
Martin Michelsen c9a61afa62 fix BB $edit name 2023-11-07 22:51:27 -08:00
Martin Michelsen 2da235caf7 don't print BB character name language markers to terminal 2023-11-07 22:24:54 -08:00
Martin Michelsen aa577b4b63 fix HP/TP results in $matcount 2023-11-07 21:50:46 -08:00
Martin Michelsen af43756899 fix typo in comment 2023-11-07 18:51:52 -08:00
Martin Michelsen 696fb8377e re-record XB test 2023-11-07 18:01:09 -08:00
Martin Michelsen cb0e9ba0b2 fix ending proxy session on non-virtual connections 2023-11-07 17:53:31 -08:00
Martin Michelsen 01f3ed7bc6 fix some endianness differences on GC/XB 2023-11-07 17:53:31 -08:00
Martin Michelsen d46e6de4f0 fix xbox redirect command 2023-11-07 17:53:31 -08:00
Martin Michelsen 71cfced5ee add xbox support 2023-11-06 23:09:09 -08:00
Martin Michelsen 4b1f5420f2 save player stats on external level up 2023-11-06 23:09:09 -08:00
Martin Michelsen 0de169e474 fix overlay creation log message 2023-11-06 23:09:09 -08:00
Matt bc8010d704 Add info about setting DNS info to DC flash
Should probably ask Flycast to do this automatically with zero values.
2023-11-06 08:50:04 -08:00
Matt 05b5998a62 Update README.md 2023-11-06 08:50:04 -08:00
Matt 7a5a3deb4d Update Flycast instructions 2023-11-06 08:50:04 -08:00
Martin Michelsen f2e84dbf78 add logging for BB bank actions 2023-11-05 18:37:11 -08:00
Martin Michelsen f0cbb08742 show item price in encode-item action 2023-11-05 18:36:57 -08:00
Martin Michelsen 1deb5e0708 fix tech disk price computation 2023-11-05 18:36:40 -08:00
Martin Michelsen 5326c1d888 fix comment on Ep3 tournament command struct 2023-11-05 18:36:23 -08:00
Martin Michelsen 519565760f add to-do list for PSOX 2023-11-05 18:36:04 -08:00
Martin Michelsen d0dbffb364 add PSOX login port 2023-11-05 12:36:01 -08:00
Martin Michelsen 5957fd62e3 add missing include 2023-11-04 22:10:52 -07:00
Martin Michelsen e8d605afe3 implement v1-encoding for v2 items 2023-11-04 21:30:24 -07:00
Martin Michelsen 25c0aa21dc remove client ID check for externally-generated item IDs 2023-11-04 09:20:42 -07:00
Martin Michelsen b06bfc13b4 don't enforce grind limits on v1/v2 2023-11-03 23:42:44 -07:00
Martin Michelsen a7e478780e deal with invalid 6x59 commands 2023-11-03 23:10:07 -07:00
Martin Michelsen f63b4bd88b don't send blank 6x5F commands when items are skipped 2023-11-03 22:15:43 -07:00
Martin Michelsen cbfcbe16f9 fix $inftp text message 2023-11-03 21:23:00 -07:00
Martin Michelsen 6b812520bc refine ObjectEntry structure 2023-11-02 23:20:00 -07:00
Martin Michelsen f1b00d3ee0 fix unit modifiers in ItemData 2023-11-02 23:19:24 -07:00
Martin Michelsen 008e59b892 fix DC QST decoder 2023-11-02 14:26:06 -07:00
Martin Michelsen 482bc5fbad use client's language when generating download quests 2023-11-02 12:07:11 -07:00
Martin Michelsen 983c6e1ebc fix English language quest fallback in menu generation 2023-11-01 23:19:49 -07:00
Martin Michelsen 1888ab61d4 add ItemRT conversion action 2023-11-01 23:19:49 -07:00
nolrinale ef5350f69b Fixing redaction 2023-10-31 11:59:59 -07:00
nolrinale 5a518c9980 Adding PSOBB localization resources 2023-10-31 11:59:59 -07:00
Martin Michelsen d97db987cd fix BB joinable quest loading bug 2023-10-31 11:04:08 -07:00
Martin Michelsen 8c85868e08 add force English flag for Tethealla BB client 2023-10-31 11:00:54 -07:00
Martin Michelsen 9e682e7c13 add TODO about quest progress flags 2023-10-31 11:00:32 -07:00
Martin Michelsen 96e478192a fix missing value in name_for_enum<EnemyType> 2023-10-31 10:08:17 -07:00
Martin Michelsen 724186a8c0 make $edit level also set stats 2023-10-31 09:57:29 -07:00
Martin Michelsen 4158f4a42a don't double-clear destroyed entity set during quest load 2023-10-30 15:27:08 -07:00
Martin Michelsen 14e6111448 remove redirection feature 2023-10-30 15:19:41 -07:00
Martin Michelsen add46095c3 document BB 0101 command 2023-10-30 14:48:02 -07:00
Martin Michelsen 5e2e38f1b5 rewrite client config; use BB state from login command 2023-10-30 13:15:41 -07:00
Martin Michelsen 47198779b7 add more info to log prefixes 2023-10-29 18:29:34 -07:00
Martin Michelsen 5ff2694ded split information menu across v1+v2 / v3 2023-10-29 18:14:09 -07:00
Martin Michelsen 138c563a40 add v2 challenge templates 2023-10-29 18:01:47 -07:00
Martin Michelsen 5ec969ece3 ignore duplicate item pickup requests 2023-10-29 18:01:44 -07:00
Martin Michelsen 4e2e423a4b fix duplicate entity ids in ItemCreator; add decision logging 2023-10-29 15:28:23 -07:00
Martin Michelsen 632af03a3f fix unidentified flag logic on v2 2023-10-29 14:39:21 -07:00
Martin Michelsen 025fc154d4 refine some BB structures 2023-10-29 13:32:29 -07:00
Martin Michelsen 1ca3d3b27f fix Anti max level on v2 2023-10-29 13:32:29 -07:00
Martin Michelsen 1b839520c9 delete unused SJIS table 2023-10-29 13:32:29 -07:00
Martin Michelsen 293df2b73a fix license autocreation 2023-10-29 13:32:29 -07:00
Martin Michelsen c496abc2bf fix flags argument to add-license shell command 2023-10-28 16:52:56 -07:00
Martin Michelsen 45c2b792f7 fix range check bug in non-v4 ItemParameterTable 2023-10-28 14:50:31 -07:00
Martin Michelsen 50a594ec60 fix logic for EXP-stealing weapons 2023-10-28 13:23:32 -07:00
Martin Michelsen b5739fff68 annotate special name table with types/amounts 2023-10-28 13:23:16 -07:00
Martin Michelsen 2c6df68af3 fix unit table in v2/v3 ItemCreator 2023-10-28 13:23:00 -07:00
Martin Michelsen 8a1c4f5f8b PhysicalData and PlayerStats are the same structure 2023-10-28 10:45:59 -07:00
Martin Michelsen 87cae99326 add default values for all command structs 2023-10-28 10:29:37 -07:00
Martin Michelsen ef939075ef fix some text handling with DC NTE 2023-10-28 01:06:43 -07:00
Martin Michelsen a6a1647801 add missing include again 2023-10-28 00:16:59 -07:00
Martin Michelsen 3ebe7dd3e2 fix camera zone layout in ep3 map disassembly 2023-10-28 00:10:55 -07:00
Martin Michelsen cc1ce099e5 fix constexpr global 2023-10-28 00:10:55 -07:00
Martin Michelsen 62dde991df add missing include 2023-10-28 00:03:59 -07:00
Martin Michelsen 75c11aeba5 refine BattleParamEntry format 2023-10-27 23:58:34 -07:00
Martin Michelsen ed05a5f6ec convert schtserv rare table to json 2023-10-27 23:04:02 -07:00
Martin Michelsen 1c2786ef43 support v2 and v3 ItemPMT files 2023-10-27 21:08:34 -07:00
Martin Michelsen 7651922dc9 add notes about mag effect activation 2023-10-27 21:08:34 -07:00
Martin Michelsen 3a21cb29fd refine PlayerInventoryItem 2023-10-27 21:08:34 -07:00
Matt 005eeb3a3f Change HUcast and RAcast shorthand to the more commonly accepted standard 2023-10-27 12:37:22 -07:00
Martin Michelsen 582fd84f5e rewrite CommonItemSet to support v2 2023-10-26 17:40:26 -07:00
Martin Michelsen 067c28dee5 fix luck material usage on v2 2023-10-26 14:41:28 -07:00
Martin Michelsen 12fbdbbcdd restrict externally-generated item ID range further 2023-10-26 11:25:27 -07:00
Martin Michelsen 700b1497d6 don't use format_data_string to serialize non-English strings 2023-10-26 00:48:29 -07:00
Martin Michelsen 20d709686a require cheats to be allowed on the server for $rand and $secid commands 2023-10-26 00:24:27 -07:00
Martin Michelsen 5c2564336e fix unicode text set codec 2023-10-26 00:03:36 -07:00
nolrinale ee4dade7ad Adding Vanilla PSOBB Rare Item Drop Data Files 2023-10-25 20:20:55 -07:00
Martin Michelsen 7476eb62d3 allow server item tables to be enabled by default 2023-10-25 18:48:22 -07:00
Martin Michelsen 6466eec106 fix externally-generated item IDs in item tracking code 2023-10-25 17:14:04 -07:00
Martin Michelsen 5f0a6f3d8e factor FloorItem struct into 6x5F format 2023-10-25 17:14:04 -07:00
Martin Michelsen 5d251361b0 fix negative bonuses in item descriptions 2023-10-25 17:14:04 -07:00
Martin Michelsen 554edf6edf don't force personal cheat flags off when cheat mode is disabled in a game 2023-10-25 17:14:04 -07:00
Martin Michelsen 0c53a0dc41 rewrite text encoding to handle non-English properly 2023-10-25 17:14:04 -07:00
Matt 6b97c628ef Update DC Serial Generator instructions once again 2023-10-22 20:31:23 -07:00
Martin Michelsen 85125a5569 add override section ID name to confirmation message 2023-10-22 09:43:02 -07:00
Martin Michelsen 1a2be3ab11 update DC serial generator instructions again 2023-10-22 09:43:02 -07:00
Martin Michelsen c0740fd21f fix v2 visual checks again 2023-10-22 09:13:29 -07:00
Martin Michelsen d2d96d9c0a get client language from login command instead of player data 2023-10-22 08:55:09 -07:00
Martin Michelsen ba7a3fc4c6 move item tables to a separate directory 2023-10-21 22:48:27 -07:00
Martin Michelsen 8f2f7670b2 make $item disk:reverser work 2023-10-21 22:17:29 -07:00
Martin Michelsen c579e47354 fix exception handling in $patch command 2023-10-21 22:17:29 -07:00
Martin Michelsen c4790068ef fix cross-version lobby appearance and name colors 2023-10-21 22:01:38 -07:00
Martin Michelsen 7b035d311f fix identified item flag during item generation 2023-10-21 20:34:59 -07:00
Martin Michelsen 713e8ff7c1 fix android skin color change for v2 limits 2023-10-21 18:51:58 -07:00
Martin Michelsen 53ebd42612 add unitxt encode/decode actions 2023-10-21 16:40:19 -07:00
2663 changed files with 54279 additions and 24383 deletions
+5 -3
View File
@@ -19,9 +19,11 @@ system/ep3/battle-records/*.mzrd
system/ep3/tournament-state.json
system/licenses.nsi
system/licenses/*.json
system/players/player_*
system/players/account_*
system/players/bank_*
system/players/*.psochar
system/players/*.psosys
system/players/*.psocard
system/players/*.nsc
system/players/*.nsa
system/patch-pc/.metadata-cache.json
system/patch-bb/.metadata-cache.json
+17 -5
View File
@@ -33,19 +33,21 @@ set (LIBEVENT_LIBRARIES
${LIBEVENT_CORE})
find_package(phosg REQUIRED)
find_package(Iconv REQUIRED)
find_package(resource_file QUIET)
# Executable definition
add_executable(newserv
set(SOURCES
src/AFSArchive.cc
src/BattleParamsIndex.cc
src/BMLArchive.cc
src/CatSession.cc
src/Channel.cc
src/ChatCommands.cc
src/ChoiceSearch.cc
src/Client.cc
src/CommonItemSet.cc
src/Compression.cc
@@ -72,6 +74,7 @@ add_executable(newserv
src/IPStackSimulator.cc
src/ItemCreator.cc
src/ItemData.cc
src/ItemNameIndex.cc
src/ItemParameterTable.cc
src/Items.cc
src/LevelTable.cc
@@ -83,7 +86,7 @@ add_executable(newserv
src/Menu.cc
src/NetworkAddresses.cc
src/PatchFileIndex.cc
src/Player.cc
src/PlayerFilesManager.cc
src/PlayerSubordinates.cc
src/ProxyCommands.cc
src/ProxyServer.cc
@@ -91,6 +94,7 @@ add_executable(newserv
src/PSOGCObjectGraph.cc
src/PSOProtocol.cc
src/Quest.cc
src/QuestAvailabilityExpression.cc
src/QuestScript.cc
src/RareItemSet.cc
src/ReceiveCommands.cc
@@ -103,13 +107,21 @@ add_executable(newserv
src/ServerState.cc
src/Shell.cc
src/StaticGameData.cc
src/TeamIndex.cc
src/Text.cc
src/TextArchive.cc
src/UnicodeTextSet.cc
src/Version.cc
src/WordSelectTable.cc
)
target_include_directories(newserv PUBLIC ${LIBEVENT_INCLUDE_DIR})
target_link_libraries(newserv phosg ${LIBEVENT_LIBRARIES} pthread)
if(resource_file_FOUND)
set(SOURCES ${SOURCES} src/ARCodeTranslator.cc)
endif()
add_executable(newserv ${SOURCES})
target_include_directories(newserv PUBLIC ${LIBEVENT_INCLUDE_DIR} ${Iconv_INCLUDE_DIRS})
target_link_libraries(newserv phosg ${LIBEVENT_LIBRARIES} ${Iconv_LIBRARIES} pthread)
if(resource_file_FOUND)
target_compile_definitions(newserv PUBLIC HAVE_RESOURCE_FILE)
@@ -131,7 +143,7 @@ foreach(LogTestCase IN ITEMS ${LogTestCases})
add_test(
NAME ${LogTestCase}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_BINARY_DIR}/newserv replay-log ${LogTestCase} --config=${CMAKE_SOURCE_DIR}/tests/config.json --require-basic-credentials)
COMMAND ${CMAKE_BINARY_DIR}/newserv --replay-log=${LogTestCase} --config=${CMAKE_SOURCE_DIR}/tests/config.json)
endforeach()
file(GLOB ScriptTestCases ${CMAKE_SOURCE_DIR}/tests/*.test.sh)
+76 -72
View File
@@ -4,9 +4,11 @@ newserv is a game server, proxy, and reverse-engineering tool for Phantasy Star
This project includes code that was reverse-engineered by the community in ages long past, and has been included in many projects since then. It also includes some game data from Phantasy Star Online itself, which was originally created by Sega.
* Background
* [History](#history)
* [Future (and to-do list)](#future)
Feel free to submit GitHub issues if you find bugs or have feature requests. I'd like to make the server as stable and complete as possible, but I can't promise that I'll respond to issues in a timely manner, because this is a personal project undertaken primarily for the fun of reverse-engineering. If you want to contribute to newserv yourself, pull requests are welcome as well.
See TODO.md for a list of known issues and future work I've curated, or go to the GitHub issue tracker for issues and requests submitted by the community.
**Table of contents**
* [Compatibility](#compatibility)
* Setup
* [Configuration](#configuration)
@@ -23,59 +25,35 @@ This project includes code that was reverse-engineered by the community in ages
* [PSO PC](#pso-pc)
* [PSO GC on a real GameCube](#pso-gc-on-a-real-gamecube)
* [PSO GC on Dolphin](#pso-gc-on-dolphin)
* [PSO BB](#pso-bb)
* [Connecting external clients](#connecting-external-clients)
* [Non-server features](#non-server-features)
## History
The history of this project essentially mirrors my development as a software engineer from the beginning of my hobby until now. If you don't care about the story, skip to the "Compatibility" or "Setup" sections below.
I originally purchased PSO GC when I heard about PSUL, and wanted to play around with running homebrew on my GameCube. This pathway eventually led to [GCARS-CS](https://github.com/fuzziqersoftware/gcars-cs), but that's another story.
<img align="left" src="s-khyps.png" /> After playing PSO for a while, both offline and online, I wrote a proxy called Khyps sometime in 2003. This was back in the days of the official Sega servers, where vulnerabilities weren't addressed in a timely manner or at all. It was common for malicious players using their own proxies or Action Replay codes (a story for another time) to send invalid commands that the servers would blindly forward, and cause the receiving clients to crash. These crashes were more than simply inconvenient; they could also corrupt your save data, destroying the hours of work you may have put into hunting items and leveling up your character.
For a while it was essentially necessary to use a proxy to go online at all, so the proxy could block these invalid commands. Khyps was designed primarily with this function in mind, though it also implemented some convenient cheats, like the ability to give yourself or other players infinite HP and allow you to teleport to different places without using an in-game teleporter.
<img align="left" src="s-khyller.png" /> After Khyps I took on the larger challenge of writing a server, which resulted in Khyller sometime in 2005. This was the first server of any type I had ever written. This project eventually evolved into a full-featured environment supporting all versions of the game that I had access to - at the time, PC, GC, and BB. (However, I suspect from reading the ancient source files that Khyller's BB support was very buggy.) As Khyller evolved, the code became increasingly cumbersome, littered with debugging filth that I never cleaned up and odd coding patterns I had picked up over the years. My understanding of the C++ language was woefully incomplete as well (as opposed to now, when it is still incomplete but not woefully so), which resulted in Khyller being essentially a C project that had a couple of classes in it.
<img align="left" src="s-aeon.png" /> Sometime in 2006 or 2007, I abandoned Khyller and rebuilt the entire thing from scratch, resulting in Aeon. Aeon was substantially cleaner in code than Khyller but still fairly hard to work with, and it lacked a few of the more arcane features I had originally written (for example, the ability to convert any quest into a download quest). In addition, the code still had some stability problems... it turns out that Aeon's concurrency primitives were simply incorrect. I had derived the concept of a mutex myself, before taking any real computer engineering classes, but had implemented it incorrectly. I made the race window as small as possible, but Aeon would still randomly crash after running seemingly fine for a few days.
At the time of its inception, Aeon was also called newserv, and you may find some beta releases floating around the Internet with filenames like `newserv-b3.zip`. I had released betas 1, 2, and 3 before I released the entire source of beta 5 and stopped working on the project when I went to college. This was around the time when I switched from writing software primarily on Windows to primarily on macOS and Linux, so Aeon beta 5 was the last server I wrote that specifically targeted Windows. (newserv, which you're looking at now, is a bit tedious to compile on Windows but does work.)
<img align="left" src="s-newserv.png" /> After a long hiatus from PSO and much professional and personal development in my technical abilities, I was reminiscing sometime in October 2018 by reading my old code archives. Somehow inspired when I came across Aeon, I spent a weekend and a couple more evenings rewriting the entire project again, cleaning up ancient patterns I had used eleven years ago, replacing entire modules with simple STL containers, and eliminating even more support files in favor of configuration autodetection. The code is now suitably modern and stable, and I'm not embarrassed by its existence, as I am by Aeon beta 5's source code and my archive of Khyller (which, thankfully, no one else ever saw).
## Future
newserv is many things - a server, a proxy, an encryption and decryption tool, a decoder of various PSO-related formats, and more. Primarily, it's a reverse-engineering project in which I try to unravel the secrets of a 20-year-old video game, for honestly no reason. Solving these problems and documenting them in code has been fun, and I'll continue to do it when my time allows.
With that said, I offer no guarantees on how or when this project will advance. Feel free to submit GitHub issues if you find bugs or have feature requests; I'd like to make the server as stable and complete as possible, but I can't promise that I'll respond to issues in a timely manner. If you feel like contributing to newserv yourself, pull requests are welcome as well.
See TODO.md for a list of known issues and future work.
## Compatibility
newserv supports several versions of PSO. Specifically:
| Version | Login | Lobbies | Games | Proxy |
|----------------|--------------|--------------|--------------|--------------|
| DC Trial | Yes (3) | Yes (3) | Yes (3) | No |
| DC Prototype | Yes (3) | Yes (3) | Yes (3) | No |
| DC V1 | Yes | Yes | Yes | Yes |
| DC V2 | Yes | Yes | Yes | Yes |
| PC | Yes | Yes | Yes | Yes |
| GC Ep1&2 Trial | Untested (1) | Untested (1) | Untested (1) | Untested (1) |
| GC Ep1&2 | Yes | Yes | Yes | Yes |
| GC Ep1&2 Plus | Yes | Yes | Yes | Yes |
| GC Ep3 Trial | Yes | Yes | Partial (4) | Yes |
| GC Ep3 | Yes | Yes | Yes | Yes |
| XBOX Ep1&2 | Untested (1) | Untested (1) | Untested (1) | Untested (1) |
| BB (vanilla) | Yes | Yes | Yes (2) | Yes |
| BB (Tethealla) | Yes | Yes | Yes (2) | Yes |
newserv supports several versions of PSO, including various development prototypes. Specifically:
| Version | Lobbies | Games | Proxy |
|----------------|--------------|--------------|--------------|
| DC Trial | Yes | Yes | No |
| DC 11/2000 | Yes | Yes | No |
| DC 12/2000 | Yes | Yes | Yes |
| DC 01/2001 | Yes | Yes | Yes |
| DC V1 | Yes | Yes | Yes |
| DC 08/2001 | Yes | Yes | Yes |
| DC V2 | Yes | Yes | Yes |
| PC | Yes | Yes | Yes |
| GC Ep1&2 Trial | Yes | Yes | Yes |
| GC Ep1&2 | Yes | Yes | Yes |
| GC Ep1&2 Plus | Yes | Yes | Yes |
| GC Ep3 Trial | Yes | Partial (1) | Yes |
| GC Ep3 | Yes | Yes | Yes |
| Xbox Ep1&2 | Yes | Yes | Yes |
| BB (vanilla) | Yes | Yes (2) | Yes |
| BB (Tethealla) | Yes | Yes (2) | Yes |
*Notes:*
1. *newserv's implementations of these versions are based on disassembly of the client executables and have never been tested.*
2. *BB games are mostly playable, but there are still some unimplemented features (for example, some quests that use rare commands may not work). Please submit a GitHub issue if you find something that doesn't work.*
3. *Support for PSO Dreamcast Trial Edition and the December 2000 prototype is somewhat incomplete and probably never will be complete. These versions are rather unstable and seem to crash often, but it's not obvious whether it's because they're prototypes or because newserv sends data they can't handle.*
4. *Creating a game works and battle setup behaves mostly normally, but starting a battle doesn't work.*
1. *Players can create games, edit decks, trade cards, and participate in auctions, but CARD battles don't work on Episode 3 Trial Edition on newserv.*
2. *Some BB-specific features are not well-tested (for example, some quests that use rare commands may not work properly). Please submit a GitHub issue if you find something that doesn't work.*
## Setup
@@ -88,8 +66,8 @@ There is a fairly recent macOS ARM64 release on the newserv GitHub repository. Y
There is a fairly recent Windows release on the newserv GitHub repository also. It's built with Cygwin, and all the necessary DLL files should be included. That said, I've only tested it on my own machine and there is no CI for Windows builds like there is for macOS and Linux, so if it doesn't work for you, please open a GitHub issue to let me know.
If you're not using a release from the GitHub repository, do this to build newserv:
1. If you're on Windows, install Cygwin. While doing so, install the `cmake`, `gcc-core`, `gcc-g++`, `git`, `libevent2.1_7`, `make`, and `zlib` packages. Do the rest of these steps inside a Cygwin shell (not a Windows cmd shell or PowerShell).
2. Make sure you have CMake and libevent installed. (On macOS, `brew install cmake libevent`; on most Linuxes, `sudo apt-get install cmake libevent-dev`; on Windows, you already did this in step 1.)
1. If you're on Windows, install Cygwin. While doing so, install the `cmake`, `gcc-core`, `gcc-g++`, `git`, `libevent2.1_7`, `make`, `libiconv-devel`, and `zlib` packages. Do the rest of these steps inside a Cygwin shell (not a Windows cmd shell or PowerShell).
2. Make sure you have CMake, libevent, and libiconv installed. (On macOS, `brew install cmake libevent libiconv`; on most Linuxes, `sudo apt-get install cmake libevent-dev`; on Windows, you already did this in step 1.)
3. Build and install phosg (https://github.com/fuzziqersoftware/phosg).
4. Optionally, install resource_dasm (https://github.com/fuzziqersoftware/resource_dasm). This will enable newserv to send memory patches and load DOL files on PSO GC clients. PSO GC clients can play PSO normally on newserv without this.
5. Run `cmake . && make` in the newserv directory.
@@ -105,20 +83,23 @@ To use newserv in other ways (e.g. for translating data), see the end of this do
### Installing quests
newserv automatically finds quests in the system/quests/ directory. To install your own quests, or to use quests you've saved using the proxy's "save files" option, just put them in that directory and name them appropriately.
newserv automatically finds quests in the subdirectories of the system/quests/ directory. To install your own quests, or to use quests you've saved using the proxy's Save Files option, just put them in one of the subdirectories there and name them appropriately. The subdirectories and their behaviors (e.g. in which game modes they should appear and for which PSO versions) is defined in the QuestCategories field in config.json.
Standard quest files should be named like `q###-CATEGORY-VERSION-LANGUAGE.EXT`, battle quests should be named like `b###-VERSION-LANGUAGE.EXT`, challenge quests should be named like `c###-VERSION-LANGUAGE.EXT` for Episode 1 or `d###-VERSION-LANGUAGE.EXT` for Episode 2. The fields in each filename are:
Within the category directories, quest files should be named like `q###-VERSION-LANGUAGE.EXT` (although the `q` is ignored, and can be any letter). The fields in each filename are:
- `###`: quest number (this doesn't really matter; it should just be unique across the PSO version)
- `CATEGORY`: ret = Retrieval, ext = Extermination, evt = Events, shp = Shops, vr = VR, twr = Tower, gv1/gv2/gv4 = Government (BB only), dl = Download (these don't appear during online play), 1p = Solo (BB only)
- `VERSION`: dn = Dreamcast NTE, d1 = Dreamcast v1, dc = Dreamcast v2, pc = PC, gcn = GameCube Trial Edition, gc = GameCube Episodes 1 & 2, gc3 = Episode 3 (see below), xb = Xbox, bb = Blue Burst
- `VERSION`: dn = Dreamcast NTE, dp = Dreamcast 11/2000 prototype, d1 = Dreamcast v1, dc = Dreamcast v2, pc = PC, gcn = GameCube Trial Edition, gc = GameCube Episodes 1 & 2, gc3 = Episode 3 (see below), xb = Xbox, bb = Blue Burst
- `LANGUAGE`: j = Japanese, e = English, g = German, f = French, s = Spanish
- `EXT`: file extension (see table below)
On .dat files, the `LANGUAGE` token may be omitted. If it's present, then that .dat file will only be used for that version of the quest; if omitted, then that .dat file will be used for all versions of the quest.
For .dat files, the `LANGUAGE` token may be omitted. If it's present, then that .dat file will only be used for that language of the quest; if omitted, then that .dat file will be used for all languages of the quest.
For example, the GameCube version of Lost HEAT SWORD is in two files named `q058-ret-gc-e.bin` and `q058-ret-gc.dat`. newserv knows these files are quests because they're in the system/quests/ directory, it knows they're for PSO GC because the filenames contain `-gc`, it knows this is the English version of the quest because the .bin filename ends with `-e` (even though the .dat filename does not), and it puts them in the Retrieval category because the filenames contain `-ret`.
Some quests (mostly battle and challenge mode quests) have additional JSON metadata files that describe how the server should handle them. This includes flags that can be used to hide the quest unless a preceding quest has been cleared, or to hide the quest unless purchased as a team reward. These metadata files are generally named similarly to their .bin and .dat counterparts, except the `VERSION` token may also be omitted if the metadata applies to all languages of the quest on all PSO versions. See system/quests/battle/b88001.json for documentation on the exact format of the JSON file.
The type identifiers (`b`, `c`, `d`, `e`, or `q`) and categories are configurable. See QuestCategories in config.example.json for more information on how to make new categories or edit the existing categories.
Some quests may also include a .pvr file, which contains an image used in the quest. These files are named similarly to their .bin and .dat counterparts.
For example, the GameCube version of Lost HEAT SWORD is in two files named `q058-gc-e.bin` and `q058-gc.dat`. newserv knows these files are quests because they're in the system/quests/ directory, it knows they're for PSO GC because the filenames contain `-gc`, it knows this is the English version of the quest because the .bin filename ends with `-e` (even though the .dat filename does not), and it puts them in the Retrieval category because the files are within the retrieval/ directory within system/quests/.
The GameCube and Xbox quest formats are very similar, but newserv treats them as different. If you want to use the same quest file for GameCube and Xbox clients, you can make one a symbolic link to the other.
There are multiple PSO quest formats out there; newserv supports all of them. It can also decode any known format to standard .bin/.dat format. Specifically:
@@ -128,6 +109,7 @@ There are multiple PSO quest formats out there; newserv supports all of them. It
| Compressed Ep3 | .bin or .mnm | Yes (4) | None (1) |
| Uncompressed | .bind and .datd | Yes | compress-prs (2) |
| Uncompressed Ep3 | .bind or .mnmd | Yes (4) | compress-prs (2) |
| Source | .bin.txt and .dat | Yes | None (5) |
| VMS (DCv1) | .bin.vms and .dat.vms | Yes | decode-vms |
| VMS (DCv2) | .bin.vms and .dat.vms | Decode (3) | decode-vms (3) |
| GCI (decrypted) | .bin.gci and .dat.gci | Yes | decode-gci |
@@ -145,6 +127,7 @@ There are multiple PSO quest formats out there; newserv supports all of them. It
2. *Similar to (1), to compress an uncompressed quest file: `newserv compress-prs FILENAME.bind FILENAME.bin` (and likewise for .datd -> .dat)*
3. *Use the decode action to convert these quests to .bin/.dat format before putting them into the server's quests directory. If you know the encryption seed (serial number), pass it in as a hex string with the `--seed=` option. If you don't know the encryption seed, newserv will find it for you, which will likely take a long time.*
4. *Episode 3 quests don't go in the system/quests directory. See the Episode 3 section below.*
5. *Quest source can be assembled into a .bin or .bind file with `newserv assemble-quest-script FILENAME.txt`. See system/quests/retrieval/q058-gc-e.bin.txt for an annotated example; this is the English GameCube version of Lost HEAT SWORD.*
Episode 3 download quests consist only of a .bin file - there is no corresponding .dat file. Episode 3 download quest files may be named with the .mnm extension instead of .bin, since the format is the same as the standard map files (in system/ep3/). These files can be encoded in any of the formats described above, except .qst.
@@ -186,7 +169,7 @@ Episode 3 state and game data is stored in the system/ep3 directory. The files i
* card-text.mnrd: Decompressed card text archive; same format as TextCardE.bin. Generally only used for debugging.
* com-decks.json: COM decks used in tournaments. The default decks in this file come from logs from Sega's servers, so the file doesn't include every COM deck Sega ever made - the rest are probably lost to time.
* maps/: Online free battle and quest maps (.mnm/.bin/.mnmd/.bind files). newserv comes with all the original online and offline maps, including Story Mode quests. If you don't want the offline maps and quests to be playable online, delete the .bind files system/ep3/maps.
* maps-download/: Download maps and quests (.mnm/.bin/.mnmd/.bind files). Files in this directory have the same format as those in the maps/ directory, but should be named like `e###-gc3-LANGUAGE.EXT` (similar to how non-Episode 3 quests are named in the system/quests/ directory). If you want a map to be available for online play and for downloading, the file must exist in both maps/ and maps-download/ (a symbolic link is acceptable).
* maps-download/: Download maps and quests (.mnm/.bin/.mnmd/.bind files). There are two subcategories by default (download maps and Trial Edition download maps), but you can add more by editing QuestCategories in config.json. Categories that have flag 0x40 (Ep3 download) set are indexed from this directory; all others are indexed from system/quests/. Files in maps-download/ subdirectories have the same format as those in the maps/ directory, but should be named like `e###-gc3-LANGUAGE.EXT` (similar to how non-Episode 3 quests are named in the system/quests/ directory). If you want a map to be available for online play and for downloading, the file must exist in both maps/ and in a maps-download/ subdirectory (a symbolic link is acceptable).
* tournament-state.json: State of all active tournaments. This file is automatically written when any tournament changes state for any reason (e.g. a tournament is created/started/deleted or a match is resolved).
There is no public editor for Episode 3 maps and quests, but the format is described fairly thoroughly in src/Episode3/DataIndexes.hh (see the MapDefinition structure). You'll need to use `newserv decompress-prs ...` to decompress .bin or .mnm files before editing them, but you don't need to compress the files again to use them - just put the .bind or .mnmd file in the maps directory and newserv will make it available.
@@ -269,12 +252,17 @@ Some commands only work on the game server and not on the proxy server. The chat
* Information commands
* `$li`: Shows basic information about the lobby or game you're in. If you're on the proxy server, shows information about your connection instead (remote Guild Card number, client ID, etc.).
* `$ping` (game server only): Shows round-trip ping time from the server to you.
* `$what` (game server only): Shows the type, name, and stats of the nearest item on the ground.
* `$matcount` (game server only): Shows how many of each type of material you've used.
* Debugging commands
* `$debug` (game server only): Enable or disable debug. You need the DEBUG permission in your user license to use this command. When debug is enabled, you'll see in-game messages from the server when you take certain actions. You'll also be placed into the highest available slot in lobbies and games instead of the lowest, which is useful for finding commands for which newserv doesn't handle client IDs properly. This setting also disables certain safeguards and allows you to do some things that might crash your client.
* `$call <function-id>`: Call a quest function on your client.
* `$quest <number>`: Load a quest by quest number. Can be used to load battle or challenge quests with only one player present.
* `$qcall <function-id>`: Call a quest function on your client.
* `$qcheck <flag-num>`: Show the value of a quest flag.
* `$qset <flag-num>` or `$qclear <flag-num>`: Set or clear a global quest flag for everyone in the game.
* `$qsync <reg-num> <value>`: Set a quest register's value on your client. `<reg-num>` should be either rXX (e.g. r60) or fXX (e.g. f60); if the latter, `<value>` is parsed as a floating-point value instead of as an integer.
* `$gc` (game server only): Send your own Guild Card to yourself.
* `$persist` (game server only): Enable or disable persistence for the current lobby or game. This determines whether the lobby/game is deleted when the last player leaves. You need the DEBUG permission in your user license to use this command because there are no game state checks when you do this. For example, if you make a game persistent, start a quest, then leave the game, the game can't be joined by anyone but also can't be deleted.
* `$sc <data>`: Send a command to yourself.
@@ -282,21 +270,28 @@ Some commands only work on the game server and not on the proxy server. The chat
* Personal state commands
* `$arrow <color-id>`: Changes your lobby arrow color.
* `$secid <section-id>`: Sets your override section ID. After running this command, any games you create will use your override section ID for rare drops instead of your character's actual section ID. To revert to your actual section id, run `$secid` with no name after it. On the proxy server, this will not work if the remote server controls item drops (e.g. on BB, or on Schtserv with server drops enabled).
* `$rand <seed>`: Sets your override random seed (specified as a 32-bit hex value). This will make any games you create use the given seed for rare enemies. This also makes item drops deterministic in Blue Burst games hosted by newserv. On the proxy server, this command can cause desyncs with other players in the same game, since they will not see the overridden random seed. To remove the override, run `$rand` with no arguments.
* `$secid <section-id>`: Sets your override section ID. After running this command, any games you create will use your override section ID for rare drops instead of your character's actual section ID. To revert to your actual section id, run `$secid` with no name after it. On the proxy server, this will not work if the remote server controls item drops (e.g. on BB, or on Schtserv with server drops enabled). If the server does not allow cheat mode anywhere (that is, "CheatModeBehavior" is "Off" in config.json), this command does nothing.
* `$rand <seed>`: Sets your override random seed (specified as a 32-bit hex value). This will make any games you create use the given seed for rare enemies. This also makes item drops deterministic in Blue Burst games hosted by newserv. On the proxy server, this command can cause desyncs with other players in the same game, since they will not see the overridden random seed. To remove the override, run `$rand` with no arguments. If the server does not allow cheat mode anywhere (that is, "CheatModeBehavior" is "Off" in config.json), this command does nothing.
* `$ln [name-or-type]`: Sets the lobby number. Visible only to you. This command exists because some non-lobby maps can be loaded as lobbies with invalid lobby numbers. See the "GC lobby types" and "Ep3 lobby types" entries in the information menu for acceptable values here. Note that non-lobby maps do not have a lobby counter, so there's no way to exit the lobby without using either `$ln` again or `$exit`. On the game server, `$ln` reloads the lobby immediately; on the proxy server, it doesn't take effect until you load another lobby yourself (which means you'll like have to use `$exit` to escape). Run this command with no argument to return to the default lobby.
* `$exit`: If you're in a lobby, sends you to the main menu (which ends your proxy session, if you're in one). If you're in a game or spectator team, sends you to the lobby (but does not end your proxy session if you're in one). Does nothing if you're in a non-Episode 3 game and no quest is in progress.
* `$patch <name>`: Run a patch on your client. `<name>` must exactly match the name of a patch on the server.
* Character data commands
* `$savechar <slot>`: Saves your current character data on the server in the specified slot (each serial number has 4 slots, numbered 1-4). These slots are separate from BB character slots; using this command does not affect BB characters.
* `$loadchar <slot>` (v1 and v2 only): Loads your character data from the specified slot. The changes will be undone if you join a game - to save your changes, disconnect from the lobby.
* `$bbchar <username> <password> <slot>`: Use this command when playing on a non-BB version of PSO. If the username and password are correct, this command converts your current character to BB format and saves it on the server in the given slot (1-4). Any character already in that slot is overwritten. (This command is similar to `$savechar`, except it overwrites a BB character slot, and can transfer characters across accounts.) Note that the character's chat data, quick menu config, and bank contents are not copied, since there is no way for the server to request those types of data.
* `$edit <stat> <value>`: Modifies your character data. If you are on V3 (GameCube/Xbox), or if the server does not allow cheat mode anywhere (that is, "CheatModeBehavior" is "Off" in config.json), this command does nothing. If you are on V1 or V2 (DC or PC, not BB), your changes will be undone if you join a game - to save your changes, disconnect from the lobby.
* Blue Burst player commands (game server only)
* `$bbchar <username> <password> <1-4>`: Use this command when playing on a non-BB version of PSO. If the username and password are correct, this command converts your current character to BB format and saves it on the server in the given slot. Any character already in that slot is overwritten.
* `$edit <stat> <value>`: Modifies your character data.
* `$bank [number]`: Switches your current bank, so you can access your other character's banks (if `number` is 1-4) or your shared account bank (if `number` is 0). If `number` is not given, switches back to your current character's bank.
* `$save`: Saves your character, system, and Guild Card data immediately. (By default, your character is saved every 60 seconds while online, and your account and Guild Card data are saved whenever they change.)
* Game state commands (game server only)
* `$maxlevel <level>`: Sets the maximum level for players to join the current game. (This only applies when joining; if a player joins and then levels up past this level during the game, they are not kicked out, but won't be able to rejoin if they leave.)
* `$minlevel <level>`: Sets the minimum level for players to join the current game.
* `$password <password>`: Sets the game's join password. To unlock the game, run `$password` with nothing after it.
* `$raretable`: Switches between using the client's or the server's drop table. No effect on BB (the server's drop table is always used). The server's rare tables are defined in JSON files in the system/rare-tables directory.
* `$itemtable`: Switches between using the client's or the server's drop table. No effect on BB (the server's drop table is always used). The server's rare tables are defined in JSON files in the system/item-tables directory.
* `$drop`: Enables or disables all item drops from boxes and enemies in the current game.
* Episode 3 commands (game server only)
* `$spec`: Toggles the allow spectators flag for Episode 3 games. If any players are spectating when this flag is disabled, they will be sent back to the lobby.
@@ -310,9 +305,9 @@ Some commands only work on the game server and not on the proxy server. The chat
* Cheat mode commands
* `$cheat`: Enables or disables cheat mode for the current game. All other cheat mode commands do nothing if cheat mode is disabled. By default, cheat mode is off in new games but can be enabled; there is an option in config.json that allows you to disable cheat mode entirely, or set it to on by default in new games.
* `$infhp` / `$inftp`: Enables or disables infinite HP or TP mode. Applies to only you. In infinite HP mode, one-hit KO attacks will still kill you.
* `$warpme <area-id>`: Warps yourself to the given area.
* `$warpall <area-id>`: Warps everyone in the game to the given area. You must be the leader to use this command, unless you're on the proxy server.
* `$next`: Warps yourself to the next area.
* `$warpme <floor-id>`: Warps yourself to the given floor.
* `$warpall <floor-id>`: Warps everyone in the game to the given floor. You must be the leader to use this command, unless you're on the proxy server.
* `$next`: Warps yourself to the next floor.
* `$swa`: Enables or disables switch assist. When enabled, the server will attempt to automatically unlock two-player doors in solo games if you step on both switches sequentially.
* `$item <desc>` (or `$i <desc>`): Create an item. `desc` may be a description of the item (e.g. "Hell Saber +5 0/10/25/0/10") or a string of hex data specifying the item code. Item codes are 16 hex bytes; at least 2 bytes must be specified, and all unspecified bytes are zeroes. If you are on the proxy server, you must not be using Blue Burst for this command to work. On the game server, this command works for all versions.
* `$unset <index>`: In an Episode 3 battle, removes one of your set cards from the field. `<index>` is the index of the set card as it appears on your screen - 1 is the card next to your SC's icon, 2 is the card to the right of 1, etc. This does not cause a Hunters-side SC to lose HP, as they normally do when their items are destroyed.
@@ -341,10 +336,12 @@ If you're emulating PSO DC or have a disc image, you can patch the appropriate f
If you're emulating PSO DC, all versions will connect to newserv by setting the following options in Flycast's `emu.cfg` file under `[network]`:
- DNS = Your newserv's server address (newserv's DNS server must be running on port 53)
- EmulateBBA = no (while some versions support the BBA, some do not, and all versions support the modem)
- EmulateBBA = yes
- Enable = yes
Once set up, the EU and US versions will work without any extra set up (other than the HL Check Disable code for USv2), while the JP versions require HL Check Disable codes to be running, and an e-mail account set up. The easiest way to set up an e-mail account is through PlanetWeb's Internet Browser for Dreamcast.
It is also necessary to save any DNS information to the flash memory of the Dreamcast to use the BBA - the easiest way to do this is to use the website option in USv2 and then choose the save to flash option.
Once set up, the EU and US versions will work without any extra set up (other than the HL Check Disable code for USv2), while the JP versions require HL Check Disable codes to be running.
If the server is running on the same machine as Flycast, this might not work, even if you point Flycast's DNS queries at your local IP address (instead of 127.0.0.1). In this case, you can modify the loaded executable in memory to make it connect anywhere you want. There is a script included with newserv that can do this on macOS; a similar technique could be done manually using scanmem on Linux or Cheat Engine on Windows. To use the script, do this:
1. Build and install memwatch (https://github.com/fuzziqersoftware/memwatch).
@@ -376,6 +373,14 @@ If you're using a version of Dolphin with tapserver support, you can make it con
3. In PSO's network settings, enable DHCP ("Automatically obtain an IP address"), set DNS server address to "Automatic", and leave DHCP Hostname as "Not set". Leave the proxy server settings blank.
4. Start an online game.
#### PSO BB
The PSO BB client has been modified and distributed in many different forms. newserv supports most, but not all, of the common distributions. Unlike other versions, it's important that the client and server have the same map files, so make sure to set up the patch directory based on the client you'll be using with newserv. (See the "Client patch directories" section for instructions on setting this up.)
The original Japanese and US versions of PSO BB should work, but you'll have to modify your hosts file or edit psobb.exe to point to your newserv instance. The original versions are packed, so this is a more involved process than simply opening the executable in a hex editor and finding/replacing some strings.
Alternatively, you can use the Tethealla client (https://archive.org/details/psobb-tethealla-client); you can find the connection addresses starting at 0x56D724 in psobb.exe. Overwrite these addresses with your server's hostname or IP address, and you should be able to connect.
### Connecting external clients
If you want to accept connections from outside your local network, you'll need to set ExternalAddress to your public IP address in the configuration file, and you'll likely need to open some ports in your router's NAT configuration - specifically, all the TCP ports listed in PortConfiguration in config.json.
@@ -395,11 +400,10 @@ newserv has many CLI options, which can be used to access functionality other th
* Convert a PSO GC or Episode 3 snapshot file to a BMP image (`decode-gci-snapshot`)
* Find the likely round1 or round2 seed for a corrupt save file (`salvage-gci`)
* Run a brute-force search for a decryption seed (`find-decryption-seed`)
* Decode Shift-JIS text to UTF-16 (`decode-sjis`)
* Convert quests in .gci, .vms, .dlq, or .qst format to .bin/.dat format (`decode-gci`, `decode-vms`, `decode-dlq`, `decode-qst`)
* Convert quests in .bin/.dat to .qst format (`encode-qst`)
* Convert text archives (e.g. TextEnglish.pr2) to JSON and vice versa (`decode-text-archive`, `encode-text-archive`)
* Disassemble quest scripts (`disassemble-quest-script`)
* Compile or disassemble quest scripts (`assemble-quest-script`, `disassemble-quest-script`)
* Format Episode 3 game data in a human-readable manner (`show-ep3-maps`, `show-ep3-cards`)
* Convert item data to a human-readable description, or vice versa (`describe-item`, `encode-item`)
* Connect to another PSO server and pretend to be a client (`cat-client`)
+10 -27
View File
@@ -1,46 +1,29 @@
## General
- Test PSOX (blocked on Insignia private server support)
- Implement server-side drops on non-BB game versions
- Find a way to silence audio in RunDOL.s
- Encapsulate BB server-side random state and make replays deterministic
- Implement choice search
- Write a simple status API
- Implement per-game logging
- Add default values in all command structures (like we use for Episode 3 battle commands)
- Check for RCE potential in 6x6B-6x6E commands
- Build an exception-handling abstraction in ChatCommands that shows formatted error messages in all cases
- Make reloading happen on separate threads so compression doesn't block active clients
- Implement decrypt/encrypt actions for VMS files
- Make UI strings localizable (e.g. entries in menus, welcome message, etc.)
- Figure out what causes the corruption message on PC proxy sessions and fix it
- Enable item tracking in battle/challenge games (everything should already be set up for it to work)
- Rewrite REL-based parsers so they don't assume any fixed offsets
- Add an idle connection timeout for proxy sessions
## Episode 3
- Make disconnecting during a tournament match cause you to forfeit the match
- Enforce tournament deck restrictions (e.g. rank checks, No Assist option) when populating COMs at tournament start time
- It may be possible to send spectators back to the waiting room after a non-tournament battle by sending 6xB4x05 with environment 0x19, then 6xB4x3B again; try this
- Add support for recording battles on the proxy server (both in primary and spectator teams)
- When `reload ep3` happens and the defs file is changed, send the new defs file to all connected players who aren't in a game (if this even works - when exactly does the client decompress the defs file from the server?)
- Make `reload licenses` not vulnerable to online players' licenses overwriting licenses on disk somehow
- Implement ranks (based on total Meseta earned)
## PSO XBOX
- Fix receiving Guild Cards from non-Xbox players
- Research the F94D quest opcode
## PSOBB
- Find any remaining mismatches in enemy IDs / experience
- Support EXP multipliers
- Sale prices for non-rare weapons with specials are computed incorrectly when buying/selling at shops
- Replace enemy list, game episode, etc. with quest data when loading a quest
- Implement trade window
- Fix some edge cases on the BB proxy server (e.g. Change Ship)
- Implement less-common subcommands
- 6xAC: Sort inventory
- 6xC1, 6xC2, 6xCD, 6xCE
- 6xCC: Exchange item for team points
- 6xD8: Add S-rank weapon special
- 6xDE: Good Luck quest
- 6xE0
- 6xE1: Gallon's Plan quest
- Implement team commands
- Test all quest item subcommands
- Check if Commander Blade effect works and implement it if not
- Figure out which quest flags are required for solo quests and write appropriate JSON files
- Figure out why Pouilly Slime EXP doesn't work
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,5 +1,5 @@
DC NTE: pso02.dricas.ne.jp
Nov 2000 proto: test1.st-pso.games.sega.net
Dec 2000 proto: sg107634.csrd.sega.co.jp
Dec 2000 proto: sg107634.csrd.sega.co.jp OR master.pso.dream-key.com
Jan 2001 proto: master.pso.dream-key.com
Aug 2001 proto (v2): ???
Aug 2001 proto (v2): game01.st-pso.games.sega.net
+692 -692
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

+3
View File
@@ -0,0 +1,3 @@
.\data\help2-0-ja.png
.\data\help0-4-ja.png
.\data\help0-5-ja.png
+6
View File
@@ -0,0 +1,6 @@
.\data\help2-0-ja.png
.\data\help0-0-ja.png
.\data\help0-1-ja.png
.\data\help0-2-ja.png
.\data\help0-3-ja.png
.\data\help0-7-ja.png
+1
View File
@@ -0,0 +1 @@
.\data\help1-1-ja.png
+1
View File
@@ -0,0 +1 @@
.\data\help1-0-ja.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+39
View File
@@ -0,0 +1,39 @@
PSOBB SUPPORT FILES, NOTES & RESOURCES
--------------------------------------------------------------------------------
CLIENT LOCALIZATION
By default PSOBB loads everything in Japanese so it requires some extra files
to properly implement the English localization from SOA, these files are offered
here inside the usbb-resources folder for your convenience they are the same ones
from the old official USBB client
To use them, you just need to drag and drop all its contents into your client's
data folder. Then if the client's internal lang flag is set correctly to English
will load all the correct texts from these files.
In case you want to play in Japanese, just use the default Tethealla client and
delete all the files including _e or _eng in the names and then the game will
default everything to its original Japanese language.
Just in case, there's the jpbb-resources folder with the latest localization
changes made on the official JPBB for an extra backup.
---------------------------------------------------------------------------------
PSOBB EP1,2,4 ORIGINAL VANILLA DROP TABLES/RATES
Included in the vanilla-tables folder I placed the original files I created for the
Schtserv vanilla for backup purposes as they are already implemented into the main
newserv logic.
These tables will offer you the experience as close as possible to the original SEGA
servers for PSOBB JP up to the latest patch before the servers shutdown, so besides a
fully functional Episode IV experience, the tables also include the latest special items
which where added to some Episode 1 and Episode 2 in Ultimate for certain section ID's
Vanilla Tables and rates are the same ones as the Schtserv Wiki for reference:
https://bbwiki.schtserv.com/index.php/Drops-ep1
https://bbwiki.schtserv.com/index.php/Drops-ep2
https://bbwiki.schtserv.com/index.php/Drops-ep4
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+3
View File
@@ -0,0 +1,3 @@
.\data\help2-0-en.png
.\data\help0-4-en.png
.\data\help0-5-en.png
+6
View File
@@ -0,0 +1,6 @@
.\data\help2-0-en.png
.\data\help0-0-en.png
.\data\help0-1-en.png
.\data\help0-2-en.png
.\data\help0-3-en.png
.\data\help0-7-en.png
+1
View File
@@ -0,0 +1 @@
.\data\help1-1-en.png
+1
View File
@@ -0,0 +1 @@
.\data\help1-0-en.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1538
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

+34 -4
View File
@@ -9,7 +9,7 @@
using namespace std;
AFSArchive::AFSArchive(std::shared_ptr<const std::string> data)
AFSArchive::AFSArchive(shared_ptr<const string> data)
: data(data) {
struct FileHeader {
be_uint32_t magic;
@@ -23,7 +23,7 @@ AFSArchive::AFSArchive(std::shared_ptr<const std::string> data)
StringReader r(*this->data);
const auto& header = r.get<FileHeader>();
if (header.magic != 0x41465300) {
if (header.magic != 0x41465300) { // 'AFS\0'
throw runtime_error("file is not an AFS archive");
}
@@ -33,7 +33,7 @@ AFSArchive::AFSArchive(std::shared_ptr<const std::string> data)
}
}
std::pair<const void*, size_t> AFSArchive::get(size_t index) const {
pair<const void*, size_t> AFSArchive::get(size_t index) const {
const auto& entry = this->entries.at(index);
if (entry.offset > this->data->size()) {
throw out_of_range("entry begins beyond end of archive");
@@ -45,7 +45,7 @@ std::pair<const void*, size_t> AFSArchive::get(size_t index) const {
return make_pair(this->data->data() + entry.offset, entry.size);
}
std::string AFSArchive::get_copy(size_t index) const {
string AFSArchive::get_copy(size_t index) const {
auto ret = this->get(index);
return string(reinterpret_cast<const char*>(ret.first), ret.second);
}
@@ -54,3 +54,33 @@ StringReader AFSArchive::get_reader(size_t index) const {
auto ret = this->get(index);
return StringReader(ret.first, ret.second);
}
string AFSArchive::generate(const vector<string>& files, bool big_endian) {
return big_endian ? AFSArchive::generate_t<true>(files) : AFSArchive::generate_t<false>(files);
}
template <bool IsBigEndian>
string AFSArchive::generate_t(const vector<string>& files) {
using U32T = typename std::conditional<IsBigEndian, be_uint32_t, le_uint32_t>::type;
StringWriter w;
w.put_u32b(0x41465300); // 'AFS\0'
w.put<U32T>(files.size());
// It seems entries are aligned to 0x800-byte boundaries, and the file's
// header is always 0x80000 (!) bytes, most of which is unused
uint32_t data_offset = 0x80000;
for (const auto& file : files) {
w.put<U32T>(data_offset);
w.put<U32T>(file.size());
data_offset = (data_offset + file.size() + 0x7FF) & (~0x7FF);
}
w.extend_to(0x80000);
for (const auto& file : files) {
w.write(file);
w.extend_to((w.size() + 0x7FF) & (~0x7FF));
}
return std::move(w.str());
}
+5
View File
@@ -25,7 +25,12 @@ public:
std::string get_copy(size_t index) const;
StringReader get_reader(size_t index) const;
static std::string generate(const std::vector<std::string>& files, bool big_endian);
private:
template <bool IsBigEndian>
static std::string generate_t(const std::vector<std::string>& files);
std::shared_ptr<const std::string> data;
std::vector<Entry> entries;
};
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <stdexcept>
#include <string>
inline void run_ar_code_translator(const std::string&, const std::string&, const std::string&) {
throw std::runtime_error("resource_file is not available; install it and rebuild newserv");
}
+154
View File
@@ -0,0 +1,154 @@
#include "ARCodeTranslator.hh"
#include <phosg/Filesystem.hh>
#include <phosg/Strings.hh>
#include <resource_file/ExecutableFormats/DOLFile.hh>
using namespace std;
void run_ar_code_translator(const std::string& initial_directory, const std::string& use_file, const std::string& command) {
string directory = initial_directory;
while (ends_with(directory, "/")) {
directory.resize(directory.size() - 1);
}
PrefixedLogger log("[ar-trans] ");
unordered_map<string, shared_ptr<DOLFile>> files;
for (const auto& filename : list_directory(directory)) {
if (ends_with(filename, ".dol")) {
string name = filename.substr(0, filename.size() - 4);
string path = directory + "/" + filename;
files.emplace(name, make_shared<DOLFile>(path.c_str()));
log.info("Loaded %s", name.c_str());
}
}
string source_filename;
shared_ptr<DOLFile> source_file;
auto find_match = [&](std::shared_ptr<DOLFile> target_file, uint32_t source_address) -> uint32_t {
const DOLFile::Section* source_section = nullptr;
for (const auto& sec : source_file->sections) {
if (source_address >= sec.address && source_address < sec.address + sec.data.size()) {
source_section = &sec;
break;
}
}
if (!source_section) {
throw runtime_error("source address not within any section");
}
size_t source_offset = source_address - source_section->address;
size_t source_bytes_available_after = source_section->data.size() - source_offset;
log.info("(find_match) Source offset = %08zX with %08zX bytes available after", source_offset, source_bytes_available_after);
for (size_t match_length = 4;
match_length < min<size_t>(source_bytes_available_after, 0x100);
match_length += 4) {
size_t num_matches = 0;
size_t last_match_address = 0;
StringReader source_r(source_section->data.data() + source_offset, match_length);
for (const auto& target_section : target_file->sections) {
for (size_t target_section_offset = 0;
target_section_offset + match_length <= target_section.data.size();
target_section_offset += 4) {
source_r.go(0);
StringReader target_r(target_section.data.data() + target_section_offset, match_length);
size_t z;
for (z = 0; z < match_length; z += 4) {
if (source_section->is_text) {
uint32_t source_opcode = source_r.get_u32b();
uint32_t target_opcode = target_r.get_u32b();
uint32_t source_class = source_opcode & 0xFC000000;
if (source_class != (target_opcode & 0xFC000000)) {
break;
}
if (source_class == 0x48000000) {
source_opcode &= 0xFC000003;
target_opcode &= 0xFC000003;
} else if (source_class == 0x40000000) {
source_opcode &= 0xFFFF0003;
target_opcode &= 0xFFFF0003;
}
if (source_opcode != target_opcode) {
break;
}
} else {
if (source_r.get_u32l() != target_r.get_u32l()) {
break;
}
}
}
if (z == match_length) {
num_matches++;
last_match_address = target_section.address + target_section_offset;
}
}
}
log.info("(find_match) For match length %zX, %zu matches found", match_length, num_matches);
if (num_matches == 1) {
return last_match_address;
} else if (num_matches == 0) {
throw runtime_error("did not find exactly one match");
}
}
throw runtime_error("scan field too long; too many matches");
};
auto handle_command = [&](const string& command) -> void {
auto tokens = split(command, ' ');
if (tokens.empty()) {
throw runtime_error("no command given");
}
strip_trailing_whitespace(tokens[tokens.size() - 1]);
if (tokens[0] == "use") {
source_filename = tokens.at(1);
source_file = files.at(source_filename);
} else if (tokens[0] == "match") {
if (!source_file) {
throw runtime_error("no source file selected");
}
uint32_t source_addr = stoul(tokens.at(1), nullptr, 16);
for (const auto& it : files) {
if (it.second == source_file) {
log.info("(%s) %08" PRIX32, it.first.c_str(), source_addr);
} else {
try {
uint32_t match_addr = find_match(it.second, source_addr);
log.info("(%s) %08" PRIX32, it.first.c_str(), match_addr);
} catch (const exception& e) {
log.error("(%s) failed: %s", it.first.c_str(), e.what());
}
}
}
} else if (!tokens[0].empty()) {
throw runtime_error("unknown command");
}
};
if (!use_file.empty()) {
source_filename = use_file;
source_file = files.at(source_filename);
}
if (!command.empty()) {
handle_command(command);
} else {
while (!feof(stdin)) {
if (!source_filename.empty()) {
fprintf(stdout, "ar-trans:%s/%s> ", directory.c_str(), source_filename.c_str());
} else {
fprintf(stdout, "ar-trans:%s> ", directory.c_str());
}
fflush(stdout);
string command = fgets(stdin);
try {
handle_command(command);
} catch (const exception& e) {
log.error("Failed: %s", e.what());
}
}
fputc('\n', stdout);
}
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include <string>
void run_ar_code_translator(const std::string& initial_directory, const std::string& use_file, const std::string& command);
+2 -2
View File
@@ -21,7 +21,7 @@ template <bool IsBigEndian>
struct BMLHeaderEntry {
using U32T = typename std::conditional<IsBigEndian, be_uint32_t, le_uint32_t>::type;
ptext<char, 0x20> filename;
pstring<TextEncoding::ASCII, 0x20> filename;
U32T compressed_size;
parray<uint8_t, 0x04> unknown_a1;
U32T decompressed_size;
@@ -52,7 +52,7 @@ void BMLArchive::load_t() {
size_t gvm_offset = offset;
offset = (offset + entry.compressed_gvm_size + 0x1F) & (~0x1F);
this->entries.emplace(entry.filename, Entry{data_offset, entry.compressed_size, gvm_offset, entry.compressed_gvm_size});
this->entries.emplace(entry.filename.decode(), Entry{data_offset, entry.compressed_size, gvm_offset, entry.compressed_gvm_size});
}
}
+15 -47
View File
@@ -9,47 +9,28 @@
using namespace std;
string BattleParamsIndex::Entry::str() const {
string a1str = format_data_string(this->unknown_a1.data(), this->unknown_a1.bytes());
return string_printf(
"BattleParamsEntry[ATP=%hu PSV=%hu EVP=%hu HP=%hu DFP=%hu ATA=%hu LCK=%hu ESP=%hu a1=%s EXP=%" PRIu32 " diff=%" PRIu32 "]",
this->atp.load(),
this->psv.load(),
this->evp.load(),
this->hp.load(),
this->dfp.load(),
this->ata.load(),
this->lck.load(),
this->esp.load(),
a1str.c_str(),
this->experience.load(),
this->difficulty.load());
}
void BattleParamsIndex::Table::print(FILE* stream) const {
auto print_entry = +[](FILE* stream, const Entry& e) {
string a1str = format_data_string(e.unknown_a1.data(), e.unknown_a1.bytes());
auto print_entry = +[](FILE* stream, const PlayerStats& e) {
fprintf(stream,
"%5hu %5hu %5hu %5hu %5hu %5hu %5hu %5hu %s %5" PRIu32 " %5" PRIu32,
e.atp.load(),
e.psv.load(),
e.evp.load(),
e.hp.load(),
e.dfp.load(),
e.ata.load(),
e.lck.load(),
e.esp.load(),
a1str.c_str(),
"%5hu %5hu %5hu %5hu %5hu %5hu %5hu %5hu %5" PRIu32 " %5" PRIu32,
e.char_stats.atp.load(),
e.char_stats.mst.load(),
e.char_stats.evp.load(),
e.char_stats.hp.load(),
e.char_stats.dfp.load(),
e.char_stats.ata.load(),
e.char_stats.lck.load(),
e.unknown_a1.load(),
e.experience.load(),
e.difficulty.load());
e.meseta.load());
};
for (size_t diff = 0; diff < 4; diff++) {
fprintf(stream, "%c ZZ ATP PSV EVP HP DFP ATA LCK ESP A1 EXP DIFF\n",
fprintf(stream, "%c ZZ ATP PSV EVP HP DFP ATA LCK ESP EXP DIFF\n",
abbreviation_for_difficulty(diff));
for (size_t z = 0; z < 0x60; z++) {
fprintf(stream, " %02zX ", z);
print_entry(stream, this->difficulty[diff][z]);
print_entry(stream, this->stats[diff][z]);
fputc('\n', stream);
}
}
@@ -82,20 +63,7 @@ BattleParamsIndex::BattleParamsIndex(
}
}
const BattleParamsIndex::Entry& BattleParamsIndex::get(
bool solo, Episode episode, uint8_t difficulty, EnemyType type) const {
return this->get(solo, episode, difficulty, battle_param_index_for_enemy_type(episode, type));
}
const BattleParamsIndex::Entry& BattleParamsIndex::get(
bool solo, Episode episode, uint8_t difficulty, size_t index) const {
if (difficulty > 4) {
throw invalid_argument("incorrect difficulty");
}
if (index >= 0x60) {
throw invalid_argument("incorrect monster type");
}
const BattleParamsIndex::Table& BattleParamsIndex::get_table(bool solo, Episode episode) const {
uint8_t ep_index;
switch (episode) {
case Episode::EP1:
@@ -111,5 +79,5 @@ const BattleParamsIndex::Entry& BattleParamsIndex::get(
throw invalid_argument("invalid episode");
}
return this->files[!!solo][ep_index].table->difficulty[difficulty][index];
return *this->files[!!solo][ep_index].table;
}

Some files were not shown because too many files have changed in this diff Show More