143 Commits

Author SHA1 Message Date
straticspaff
022eaccbba Merge remote-tracking branch 'origin/main' into feature/restore-history 2023-09-27 21:14:24 +01:00
Sophie Tagliabue
9d22e620dc Merge pull request #1 from Ellie42/fix-full-party-bug
Add a quick fix to allow partying with 4 players
2020-03-12 06:58:15 +00:00
Sophie
c22793e102 Add a quick fix to allow partying with 4 players 2020-03-11 07:43:19 +00:00
Andrew Gutekanst
985efa797c Fix migration 2020-03-10 20:44:57 -04:00
Andrew Gutekanst
e6f693f222 Merge pull request #15 from Ellie42/improve-chat
Improve chat and additional small fixes for party interaction
2020-03-10 18:30:16 -04:00
Andrew Gutekanst
e938478107 Merge pull request #14 from SirFist/master
Working events, active features, some basic save stuff, etc.
2020-03-10 18:25:29 -04:00
SirFist
1d01dba380 move migration out of existing file 2020-03-10 17:45:20 +00:00
Sophie
ab7a52caea Fix silly locking issue 2020-03-10 08:55:52 +00:00
Sophie
081deba17b Add stage locks on find session function 2020-03-10 08:30:07 +00:00
Sophie
4c27b99e9a Add support for private messages 2020-03-10 08:25:09 +00:00
Sophie
892f89eba9 Add support for party chat in town 2020-03-10 07:56:01 +00:00
Sophie
78fe5c85ef Add support for players logging out and closing client
Removed seemingly unnecessary castedBinary messages on character login
2020-03-09 19:15:16 +00:00
Sophie
ba3df8d4d1 Remove unnecessary messages, these were covered by recasting user bins 2020-03-09 18:05:01 +00:00
Sophie
83becc4c84 Fix perpetual stage lock
Cleanup
2020-03-09 07:37:16 +00:00
Sophie
9710f1cc43 Rollback inadvertent file commit 2020-03-09 07:18:04 +00:00
Sophie
320ce7d783 Fix conflicts 2020-03-09 07:16:45 +00:00
Sophie
927f6e9419 Limit recipients of party chat messages
Add vendor to gitignore
2020-03-09 07:06:05 +00:00
SirFist
7815768741 Merge branch 'master' of https://github.com/Andoryuuta/Erupe 2020-03-09 01:04:23 +00:00
Andrew Gutekanst
c7862f38bf Merge pull request #12 from Andoryuuta/fix-mp-quests
Fix multiplayer questing
2020-03-08 20:55:40 -04:00
Andrew Gutekanst
615b75d101 Fix multiplayer questing
This fixes an issue with MsgSysCastBinary->MsgSysCastedBinary forwarding
and adds a basic stage-reservation system, allowing for some multiplayer
quests to work.
2020-03-08 20:50:27 -04:00
SirFist
1edd48f480 Merge branch 'master' of https://github.com/Andoryuuta/Erupe 2020-03-09 00:32:36 +00:00
SirFist
e94fc6da20 Active features, diva defense, super basic pass on ravi npc + merc save, expanded earth value 2020-03-08 23:49:51 +00:00
Andrew Gutekanst
e41335b079 Fix MsgSysCastedBinary
Fixes a two-month-old typo in the Build method.
Implements the parse method.
2020-03-08 19:30:30 -04:00
Andrew Gutekanst
9c67910bdc Merge pull request #11 from Andoryuuta/save_compression
Save compression
2020-03-08 19:20:25 -04:00
Andrew Gutekanst
343333217f Cleanup delta compression 2020-03-08 19:07:02 -04:00
Andrew Gutekanst
8e53b6cc63 Fix hunter navi defualt popup 2020-03-08 19:00:45 -04:00
Sophie
1041cac476 Add config option to log outbound messages 2020-03-07 17:37:04 +00:00
Sophie
b526e66821 Add chat type checks based on existing comments
Add basic support for clients reserving stages
Remove unnecessary packets
Add max player count to stages
2020-03-07 17:30:07 +00:00
Sophie
795028a1ca Clients in stage are now notified when player chooses a quest 2020-03-07 14:21:08 +00:00
Sophie
ac40e679fe Add mhfpacket wrapper for party join message 2020-03-06 21:23:57 +00:00
Sophie
2d9a26df75 Add support for more chat types
Add joining player -> part host notification messages
2020-03-06 19:22:37 +00:00
Andrew Gutekanst
a7656189a4 Fix hunter navi saving 2020-03-04 11:18:41 -05:00
Andrew Gutekanst
8ae6cb2e96 Use bytes.Reader for deltacomp 2020-03-04 10:52:34 -05:00
Andrew Gutekanst
d3c94a26e8 Update GR saving 2020-03-04 10:30:21 -05:00
Andrew Gutekanst
3ba2995afa Update delta/diff compression impl 2020-03-03 21:13:13 -05:00
Andrew Gutekanst
401834008c Move null compression to subpackage 2020-03-03 20:21:41 -05:00
Andrew Gutekanst
933ed7943d Merge pull request #10 from Andoryuuta/minor-cleanup
Minor cleanup
2020-03-03 10:14:11 -05:00
Andrew Gutekanst
d300098838 Make changed parsers size-accurate 2020-03-03 02:32:00 -05:00
Andrew Gutekanst
e90cc176ec Replace tab with spaces in config.json 2020-03-02 23:51:01 -05:00
Andrew Gutekanst
af22707b48 go fmt 2020-03-02 23:36:27 -05:00
Andrew Gutekanst
82f92e2f24 Merge pull request #9 from SirFist/master
Saves, quest fixes, facility fixes etc.
2020-03-02 20:43:07 -05:00
SirFist
52ae5f56a0 fixed a dumb 2020-03-02 03:24:05 +00:00
SirFist
62648f6717 Revert "MsgMhfTransferItem"
This reverts commit 0daf7b55d4.
2020-03-02 03:22:15 +00:00
SirFist
f5033d1517 Revert "look it's 3am ok"
This reverts commit e0aae07a43.
2020-03-02 03:22:08 +00:00
SirFist
e0aae07a43 look it's 3am ok 2020-03-02 03:20:56 +00:00
SirFist
0daf7b55d4 MsgMhfTransferItem
Another post-quest packet that black screens without a response.
2020-03-02 03:20:10 +00:00
SirFist
ad5cd8212a Launcher char name, hr, weapon 2020-03-01 06:30:09 +00:00
SirFist
8607ff05f9 Armour, Deco and Sigil Preset Saving 2020-03-01 05:18:34 +00:00
SirFist
861e53cb7a SaveFavoriteQuests
This packet actually turns up with proper load handling which will  brick your saving functionality without it
2020-03-01 00:47:33 +00:00
SirFist
a0f585b3e3 Stub for if no quest lists in db 2020-02-29 21:33:44 +00:00
SirFist
b024e3c5f2 standardise config buttons 2020-02-29 00:37:03 +00:00
SirFist
aa58fe48ed Merge branch 'master' of https://github.com/Andoryuuta/Erupe 2020-02-29 00:29:58 +00:00
SirFist
4926d0cae2 Stopping a few pop ups appearing
I added too many bytes to load
2020-02-29 00:18:35 +00:00
SirFist
0a664b9fde Post quest packets
Should fix most of the things that were causing black screens after quest completion.
2020-02-28 22:33:53 +00:00
SirFist
80c5701a9a Quest lists can be added, tower skills
You need to check your local shrek fansite if you want the working quest lists since they aren't consistent within packet captures.
2020-02-28 06:57:29 +00:00
SirFist
4f67e3de67 More saves, launcher tweaks
Added config at char select screen
Transmog saving and loading (unlocks are not yet tackled and it is global rn)
Sigil saving (can break, initial pass of save)
Null compression and decompression functions.
First pass of the diff save function.
Disabled stamp cards
2020-02-27 23:42:46 +00:00
SirFist
2999fb14d6 All house facilities acessible
Likely there are missing persistent save features around the My Garden gooks and My Mission tasks.
2020-02-26 17:31:49 +00:00
SirFist
c54811729f more saves, guildcard, road, shops
PARTNER save/load handling
OTOMO_AIROU save/load handling
Basic groundwork for HUNTER_NAVI save/load handling
Basic groundwork for PLATE_BOX save/load handling
Basic groundwork for PLATE_DATA save/load handling
Basic groundwork for PLATE_MYSET save/load handling
Basic groundwork for DECO_MYSET save/load handling
Basic groundwork for RENGOKU_DATA save/load handling
Handling for MSG_MHF_GET_RENGOKU_BINARY, enables road. Place rengoku_data.bin from either /dat/ in install or from a packet capture in the /bin/ folder for this
Handling for MSG_MHF_UPDATE_CAFEPOINT allowing access to guildcard
Handling for MSG_MHF_GET_PAPER_DATA which fixes the issue of all save functionality immediately breaking after loading into town proper
Handling for MSG_MHF_ENUMERATE_SHOP enabling access to all shops
Handling for MSG_MHF_GET_TENROUAIRAI enabling access to duremudira and janky tower
Handling for MSG_MHF_GET_GACHA_POINT, should be added to database as it's functionally a persistent save that's reduced when MSG_MHF_USE_GACHA_POINT is triggered
Handling for MSG_MHF_GET_TREND_WEAPON, stops smith breaking when you're high enough rank for it to pull recommendations
Devmode config option for using a fixed stage ID to allow entry into blacksmith and other areas
Delivered quest file will automatically be replaced if you have a quest_override.bin in the bin folder, keep in mind this will break badly depending on quest counter data for the quest to be replaced
2020-02-26 14:32:12 +00:00
Andrew Gutekanst
29482521e2 Add config button to launcher 2020-02-26 00:40:04 -05:00
Andrew Gutekanst
1d49e279e3 Merge pull request #8 from Andoryuuta/packet-parsers
Packet parsers
2020-02-23 21:15:35 -05:00
Andrew Gutekanst
6e6183022d Add MsgMhfAcquireExchangeShop parser 2020-02-23 20:30:43 -05:00
Andrew Gutekanst
9182097411 Add MsgMhfAcquireDistItem size parser 2020-02-23 20:30:20 -05:00
Andrew Gutekanst
52107be3ff Add MsgMhfAcquireCafeItem size parser 2020-02-23 20:15:30 -05:00
Andrew Gutekanst
1e33ed84c6 Add parsers for some ackHandle-only packets 2020-02-23 18:56:54 -05:00
Andrew Gutekanst
112dc03acc Update README.md 2020-02-23 11:16:32 -05:00
Andrew Gutekanst
f86845eb14 Merge pull request #5 from Andoryuuta/multiplayer-jp
Multiplayer JP
2020-02-22 22:59:23 -05:00
Andrew Gutekanst
35f34d31db Add dev options to config 2020-02-22 22:46:00 -05:00
Andrew Gutekanst
1d8eec2280 Implement handlers for stage movement and quest completion 2020-02-22 22:22:50 -05:00
Andrew Gutekanst
c505686893 Document charID-based house stageID 2020-02-22 22:18:16 -05:00
Andrew Gutekanst
172b5decf4 Implement multiple packet parsers 2020-02-22 22:17:10 -05:00
Andrew Gutekanst
ecc0e49497 Fix major crypto bug
`cryptKeyTruncByte` was incorrectly typed as a byte when 1 was added.
This caused `cryptKeyTruncByte` to wrap around to 0 when it was 0xFF,
resulting in an incorrect multiplication by zero, breaking [en|de]cryption entirely.
2020-02-22 21:03:35 -05:00
Andrew Gutekanst
fff92b16ed Add bruteforce fallback for out-of-sync crypto 2020-02-22 11:20:52 -05:00
Andrew Gutekanst
fe786617d4 Implement scenario getfile packet and counter stub 2020-02-21 14:59:10 -05:00
Andrew Gutekanst
8cea6235c8 Implement stage object deletion 2020-02-19 08:13:41 -05:00
Andrew Gutekanst
e5f2650871 Add prayer/diva fountain stage 2020-02-19 08:11:24 -05:00
Andrew Gutekanst
99c965e3b6 Combine MsgSysEnterStage with MsgSysMoveStage 2020-02-07 18:16:33 -05:00
Andrew Gutekanst
315449aa33 Document MsgSysEnumerateStage resp fields 2020-02-07 13:36:24 -05:00
Andrew Gutekanst
50b21094f2 Implement user binary parts propagation 2020-02-05 13:15:26 -05:00
Andrew Gutekanst
8b65fc7495 Fix client crash and implement quest loading
Fixed client crashes caused by handleMsgMhfEnumeratePrice and handleMsgMhfEnumerateRanking
wherein the server's response didn't contain enough data, causing the client to read uninitalized memory.

Implemented quest loading handlers GetFile, WaitStageBinary, and UnlockStage, as well as correcting the IssueLogkey handler.
2020-02-05 05:03:28 -05:00
Andrew Gutekanst
d4370c66ad Add MSG_SYS_END to all sent packets 2020-02-05 05:00:20 -05:00
Andrew Gutekanst
4e1cef9bf3 Implement stage binaries, stack locking, and logkeys 2020-02-03 22:56:54 -05:00
Andrew Gutekanst
5924db9b42 Remove debug code from entrance server 2020-02-03 15:27:38 -05:00
Andrew Gutekanst
f17d1db9a7 Implement packets & handlers for loading existing character 2020-02-03 15:25:04 -05:00
Andrew Gutekanst
773429ce15 Make char savedata persistent 2020-02-03 14:07:33 -05:00
Andrew Gutekanst
0893f75c3f Update README.md 2020-02-01 17:47:16 -05:00
Andrew Gutekanst
eb491093f8 Make custom launcher files a config option 2020-02-01 17:40:47 -05:00
Andrew Gutekanst
1929b8823d Write missing packet opcodes 2020-02-01 16:22:13 -05:00
Andrew Gutekanst
99ceeb6872 Fix entree object notifications 2020-01-24 15:28:08 -05:00
Andrew Gutekanst
69ca0c13ac Add temp user binary parts 2 & 3 2020-01-24 13:38:38 -05:00
Andrew Gutekanst
cf91478abb Fix typo in MsgSysGetUserBinary 2020-01-23 21:07:29 -05:00
Andrew Gutekanst
1b74b6496e Implement MsgSysGetUserBinary name stub 2020-01-23 21:06:25 -05:00
Andrew Gutekanst
23838bdb78 Add debug logging and stage entry fixes 2020-01-23 20:52:52 -05:00
Andrew Gutekanst
86d4ec55cb Implement MsgSysPositionObject Build 2020-01-23 20:32:15 -05:00
Andrew Gutekanst
3b443344a2 Make object ID start at 1 2020-01-23 20:29:56 -05:00
Andrew Gutekanst
0ac35f8743 Fix Stage init 2020-01-23 20:22:42 -05:00
Andrew Gutekanst
1afe6860e2 Print recovered panic error 2020-01-23 20:15:56 -05:00
Andrew Gutekanst
b1b4f390f0 Stage object notification test 2020-01-23 19:59:26 -05:00
Andrew Gutekanst
28e0dafd54 Stage/objects test 2020-01-23 19:29:19 -05:00
Andrew Gutekanst
10c80322af Implement MsgSysSetStageBinary parser 2020-01-23 16:49:00 -05:00
Andrew Gutekanst
cb275a7a18 Implement MsgSysSetStagePass parser 2020-01-23 15:59:30 -05:00
Andrew Gutekanst
865ba378ec Update MsgSysCreateStage fields 2020-01-23 15:53:45 -05:00
Andrew Gutekanst
ea13520ca9 Implement MsgSysReserveStage 2020-01-23 14:46:15 -05:00
Andrew Gutekanst
a92b5b0b93 Fix typo deadlock 2020-01-22 18:22:33 -05:00
Andrew Gutekanst
cf3cafa929 Implement MsgSysCreateStage 2020-01-22 18:17:23 -05:00
Andrew Gutekanst
5a67d689e0 Fix MsgSysCreateObject stage lookup 2020-01-22 18:03:02 -05:00
Andrew Gutekanst
fa245e53fb Implement MsgSysEnumerateStage w/ stage map 2020-01-22 17:53:27 -05:00
Andrew Gutekanst
b898614ddc Add MsgMhfCheckWeeklyStamp 2020-01-21 20:21:12 -05:00
Andrew Gutekanst
76fe663ee1 Add MsgSysReserve203/IsUpdateGuildMsgBoard 2020-01-21 20:01:32 -05:00
Andrew Gutekanst
4c839440cd Fix typo 2020-01-21 18:12:34 -05:00
Andrew Gutekanst
d0234c85ab Add MsgMhfGetUdTacticsFollower stub 2020-01-21 18:10:37 -05:00
Andrew Gutekanst
fa608fa555 Initial chat prototype 2020-01-19 12:52:57 -05:00
Andrew Gutekanst
e6d7b7b9c2 Fix sum32 checksum 2020-01-14 11:23:27 -05:00
Andrew Gutekanst
5f1d429c12 Add graceful shutdown to channel server 2020-01-13 18:36:55 -05:00
Andrew Gutekanst
30219b8bcf Change project dir structure 2020-01-13 17:32:49 -05:00
Andrew Gutekanst
e5257eb6ed Refactor servers 2020-01-13 17:19:29 -05:00
Andrew Gutekanst
0922ff4f9c Run go mod tidy 2020-01-01 10:53:00 -05:00
Andrew Gutekanst
5a9c639172 Change sign server default response 2020-01-01 10:50:22 -05:00
Andrew Gutekanst
953870867e Fix entrance server IPv4 encoding 2020-01-01 10:35:14 -05:00
Andrew Gutekanst
fbcd878e72 Remove test.py step from readme 2020-01-01 08:47:37 +09:00
Andrew Gutekanst
1c6b7ef257 Port entrance server to Go 2020-01-01 08:46:36 +09:00
Andrew Gutekanst
caf9fc91ed Port entrance server crypto to Go 2020-01-01 06:42:36 +09:00
Andrew Gutekanst
6367789c73 Partially cleanup test.py 2019-12-31 08:14:23 +09:00
Andrew Gutekanst
501cfc2267 Add multi-region launcher support
Add custom launcher as well as support for both the original TW and JP
launchers.
2019-12-30 07:38:48 +09:00
Andrew Gutekanst
a014b0d3b9 Update .gitignore 2019-12-30 07:37:38 +09:00
Andrew Gutekanst
8792908a66 Remove old channel server impl 2019-12-29 05:30:17 +09:00
Andrew Gutekanst
61738b6f23 Update README.md 2019-12-27 08:40:58 +09:00
Andrew Gutekanst
4846a024eb Add MSG_MHF_GET_GACHA_POINT parser 2019-12-27 08:25:52 +09:00
Andrew Gutekanst
b756a02e6e Really fix MSG_MHF_SAVE_FAVORITE_QUEST 2019-12-27 08:25:23 +09:00
Andrew Gutekanst
78cc2be2c4 Fix MSG_MHF_SAVE_FAVORITE_QUEST parser 2019-12-27 08:19:49 +09:00
Andrew Gutekanst
5b9ec1c983 Add MSG_MHF_SAVE_FAVORITE_QUEST parser 2019-12-27 08:19:06 +09:00
Andrew Gutekanst
f3a6e72f43 Move MHF_GET_RENGOKU_RANKING_RANK logic 2019-12-27 08:09:20 +09:00
Andrew Gutekanst
81c9b22b11 Restore old packet logic temporarily 2019-12-27 04:42:06 +09:00
Andrew Gutekanst
6a23130772 Update parsers 2019-12-27 04:41:05 +09:00
Andrew Gutekanst
d4dddf01dd Implement some handlers 2019-12-27 04:04:03 +09:00
Andrew Gutekanst
d1a9d5a7d0 Implement some packet parsers 2019-12-27 04:01:29 +09:00
Andrew Gutekanst
e38b725662 Autogenerate packet type stubs 2019-12-27 02:45:00 +09:00
Andrew Gutekanst
d893059971 Update README.md 2019-12-26 23:02:34 +09:00
Andrew Gutekanst
519238f54d Channel server refactoring 2019-12-26 22:23:59 +09:00
Andrew Gutekanst
319cfcb2f7 Now gets ingame! 2019-12-24 16:06:40 +09:00
Andrew Gutekanst
e5066d4f8b Hackily get the client to a channel server 2019-12-24 00:20:35 +09:00
Andrew Gutekanst
7aef17f7d9 Progress with binary8 encoding 2019-12-20 06:00:47 +09:00
Andrew Gutekanst
96ec589651 Initial commit 2019-12-19 21:53:28 +09:00
Andrew Gutekanst
fc5b1ac3b5 Add .gitignore 2019-12-19 21:53:15 +09:00
494 changed files with 10099 additions and 7291 deletions

View File

@@ -1,48 +0,0 @@
name: Create and publish a Docker image
# Configures this workflow to run every time a tag is created.
on:
push:
tags:
- '*'
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -1,15 +1,6 @@
name: Build
on:
push:
paths:
- 'common/**'
- 'config/**'
- 'network/**'
- 'server/**'
- 'go.mod'
- 'go.sum'
- 'main.go'
on: [push]
jobs:
build:

2
.gitignore vendored
View File

@@ -7,5 +7,3 @@ savedata/*/
*.exe
*.lnk
*.bat
/docker/db-data
screenshots/*

View File

@@ -1,30 +0,0 @@
# List of authors who contributed to Erupe
## Point of current development
The project is currently developed under https://github.com/ZeruLight/Erupe
## History of development
Development of this project dates back to 2019, and was developed under various umbrellas over time:
* Cappuccino (Fist/Ando/Ellie42) ("The Erupe Developers"), 2019-2020 (https://github.com/Ellie42/Erupe / https://github.com/ricochhet/Erupe-Legacy) (Still active closed source)
* Einherjar Team, ????-2022 Feb (There is no git history for this period, this team's work was taken and used as a foundation for future repositories)
* Community Edition, 2022 (https://github.com/xl3lackout/Erupe)
* sekaiwish Fork, 2022 (https://github.com/sekaiwish/Erupe)
* ZeruLight, 2022-2023 (https://github.com/ZeruLight/Erupe)
## Authorship of the code
Authorship is assigned for each commit within the git history, which is stored in these git repos:
* https://github.com/ZeruLight/Erupe
* https://github.com/Ellie42/Erupe
* https://github.com/ricochhet/Erupe-Legacy
* https://github.com/xl3lackout/Erupe
Note the divergence between Ellie42's branch and xl3lackout's where history has been lost.
Unfortunately, we have no detailed information on the history of Erupe before 2022.
If somebody can provide information, please contact us, so that we can make this history available.
## Exceptions with third-party libraries
The third-party libraries have their own way of addressing authorship and the authorship of commits importing/updating
a third-party library reflects who did the importing instead of who wrote the code within the commit.
The authors of third-party libraries are not explicitly mentioned, and usually is possible to obtain from the files belonging to the third-party libraries.

View File

@@ -1,14 +0,0 @@
FROM golang:1.21-alpine3.19
ENV GO111MODULE=on
WORKDIR /app/erupe
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
CMD [ "go", "run", "." ]

141
README.md
View File

@@ -1,18 +1,15 @@
# Erupe
## Client Compatibility
## Client Compatiblity
### Platforms
- PC
- PlayStation 3
- PlayStation Vita
- Wii U (Up to Z2)
### Versions (ClientMode)
- All versions after HR compression (G10-ZZ) have been tested extensively and have great functionality.
- All versions available on Wii U (G3-Z2) have been tested and should have good functionality.
- The second oldest found version is Forward.4 (FW.4), this version has basic functionality.
- The oldest found version is Season 6.0 (S6.0), however functionality is very limited.
If you have an **installed** copy of Monster Hunter Frontier on an old hard drive, **please** get in contact so we can archive it!
### Versions
- ZZ
- Z2
- Z1
## Setup
@@ -32,21 +29,119 @@ If you want to modify or compile Erupe yourself, please read on.
3. Edit [config.json](./config.json) such that the database password matches your PostgreSQL setup.
4. Run `go build` or `go run .` to compile Erupe.
## Docker
Please see [docker/README.md](./docker/README.md). This is intended for quick installs and development, not for production.
## Schemas
We source control the following schemas:
- Initialization Schema: This initializes the application database to a specific version (9.1.0).
- Update Schemas: These are update files that should be ran on top of the initialization schema.
- Patch Schemas: These are for development and should be run after running all initialization and update schema. These get condensed into `Update Schemas` and deleted when updated to a new release.
- Bundled Schemas: These are demo reference files to give servers standard set-ups.
Note: Patch schemas are subject to change! You should only be using them if you are following along with development.
## Resources
- [Quest and Scenario Binary Files](https://files.catbox.moe/xf0l7w.7z)
- [Mezeporta Square Discord](https://discord.gg/DnwcpXM488)
- [PewPewDojo Discord](https://discord.gg/CFnzbhQ)
## Configuration
This portion of the documentation goes over the `config.json` file.
### General Configuration
| Variable | Description | Default | Options |
|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|---------------------------------|
| Host | The IP or host address the server is running from | 127.0.0.1 | |
| BinPath | The bin path folder is where you place files needed for various parts of the game such as scenario and quest files | bin | |
| Language | This is the language the server will run in. Only English `en` and Japanese `ja` are available, if you wish to contribute to tranlation, get in touch | en | en/jp |
| DisableSoftCrash | | false | |
| HideLoginNotice | This hides the notices that appear on login from `LoginNotices` | true | |
| LoginNotices | This is where you place notices for users, you can have multiple notices | | |
| PatchServerManifest | | | |
| PatchServerFile | | | |
| ScreenshotAPIURL | This is the URL you want user sreenshots to go to | | |
| DeleteOnSaveCorruption | This option deletes a users save from the database if they corrupt it, can be used as punishment for cheaters | false | |
| ClientMode | This tells the server what client version it should target | ZZ | Check compatible versions above |
| DevMode | This enables DevModeOptions to be configured | true | |
### `DevModeOptions` Configuraiton
| Variable | Description | Default | Options |
|----------------------|---------------------------------------------------------------------------------------------|----------|----------------------------------|
| AutoCreateAccount | This allows users that don't exist to auto create there account from initial login | true | |
| CleanDB | This cleans the database down | false | |
| MaxLauncherHR | This sets the launcher value to HR7 to allow you to break World HR requirements | false | |
| LogInboundMessages | This will allow inbound messages to be logged to stdout | false | |
| LogOutboundMessages | This will allow outbound messages to be logged to stdout | false | |
| MaxHexdumpLength | This is the maximum amount of hex bytes that will be dumped to stdout | 0 | |
| DivaEvent | This overrides the Diva event stage in game | 2 | 0/1/2/3/-1 |
| FestaEvent | This overrides the Hunter Festival event stage in game | 2 | 0/1/2/3/-1 |
| TournamentEvent | This overrides the Hunter Tournament event stage in game | 2 | 0/1/2/3/-1 |
| MezFesEvent | Enables whether the MezFes event & World are active | true | |
| MezFesAlt | Switches the multiplayer MezFes event | false | |
| DisableTokenCheck | This disables the random token that is generated at login from being checked, very insecure | false | |
| QuestDebugTools | Enable various quest debug logs | false | |
| EarthStatusOverride | Enables Pallone Fest, Tower and Conquest War events | 0 | 2=Conquest, 11=Pallone, 21=Tower |
| EarthIDOverride | A random event ID | 0 | |
| EarthMonsterOverride | Sets the ID of the monster targeted in the Conquest War | 0 | |
| SaveDumps.Enables | Enables save dumps to a folder that is set at `SaveDumps.OutputDir` | true | |
| SaveDumps.OutputDir | The folder that save dumps are saved to | savedata | |
### `GameplayOptions` Configuraiton
| Variable | Description | Default | Options |
|----------------------|-----------------------------------------------------------------------------|---------|---------|
| FeaturedWeapons | Number of Active Feature weapons to generate daily | 0 | |
| MaximumNP | Maximum number of NP held by a player | 100000 | |
| MaximumRP | Maximum number of RP held by a player | 100000 | |
| DisableLoginBoost | Disables the Login Boost system | false | |
| DisableBoostTime | Disables the daily NetCafe Boost Time | false | |
| BoostTimeDuration | The number of minutes NetCafe Boost Time lasts for | 120 | |
| GuildMealDuration | The number of minutes a Guild Meal can be activated for after cooking | 60 | |
| BonusQuestAllowance | Number of Bonus Point Quests to allow daily | 3 | |
| DailyQuestAllowance | Number of Daily Quests to allow daily | 1 | |
| MezfesSoloTickets | Number of solo tickets given weekly | 10 | |
| MezfesGroupTickets | Number of group tickets given weekly | 4 | |
| GUrgentRate | Adjusts the rate of G Urgent quests spawning | 10 | |
| GCPMultiplier | Adjusts the multiplier of GCP rewarded for quest completion | 1.00 | |
| GRPMultiplier | Adjusts the multiplier of G Rank Points rewarded for quest completion | 1.00 | |
| GSRPMultiplier | Adjusts the multiplier of G Skill Rank Points rewarded for quest completion | 1.00 | |
| GZennyMultiplier | Adjusts the multiplier of G Zenny rewarded for quest completion | 1.00 | |
| MaterialMultiplier | Adjusts the multiplier of Monster Materials rewarded for quest completion | 1.00 | |
| ExtraCarves | Grant n extra chances to carve ALL carcasses | 0 | |
| DisableHunterNavi | Disables the Hunter Navi | false | |
| EnableHiganjimaEvent | Enables the Higanjima event in the Rasta Bar | false | |
| EnableNierEvent | Enables the Nier event in the Rasta Bar | false | |
| DisableRoad | Disables the Hunting Road | false | |
### Discord
There is limited Discord capability in Erupe. The feature allows you to replay messages from your server into a channel.
This may be either be removed or revamped in a future version.
### Commands
There are several chat commands that can be turned on and off. Most of them are really for admins or debugging purposes.
| Name | command | Description | Options |
|----------|----------------|--------------------------------------------|---------------------|
| Rights | !rights VALUE | Sets the rights integer for your account | |
| Teleport | !tele X,Y | Teleports user to specific x,y coordinate | |
| Reload | !reload | Reloads all users and character objects | |
| KeyQuest | !kqf FLAGS | Sets the Key Quest Flag for your character | |
| Course | !course OPTION | Enables/Disables a course for your account | HL,EX,Premium,Boost |
| PSN | !psn USERNAME | Links the specified PSN to your account | |
### Ravi Sub Commands
| Name | command | Description |
|----------|----------------------------------|-------------------------------|
| Raviente | !ravi start | Starts Ravi Event |
| Raviente | !ravi cm / !ravi checkmultiplier | Checks Ravi Damage Multiplier |
| Raviente | !ravi ss | Send Sedation Support |
| Raviente | !ravi sr | Send Resurrection Support |
| Raviente | !ravi rs | Request Sedation Support |
## World `Entries` config
| Config Item | Description | Options |
|-------------|------------------|------------------------------------------------------------|
| Type | Server type. | 1=Normal, 2=Cities, 3=Newbie, 4=Tavern, 5=Return, 6=MezFes |
| Season | Server activity. | 0=Green/Breeding, 1=Orange/Warm, 2=Blue/Cold |
### `Recommend`
This sets the types of quest that can be ordered from a world.
* 0 = All quests
* 1 = Up to 2 star quests
* 2 = Up to 4 star quests
* 4 = All Quests in HR (Enables G Experience Tab)
* 5 = Only G rank quests
* 6 = Mini games world there is no place to order quests

View File

@@ -0,0 +1,2 @@
place your quest .bin files here
e.g. 22031d0.bin

2372
bin/quests/desktop.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,391 @@
BEGIN;
INSERT INTO fpoint_items (item_type, item_id, quantity, fpoints, trade_type) VALUES
(7,8895,1,500,0),
(7,8891,1,300,0),
(7,8892,1,300,0),
(7,8893,1,300,0),
(7,8894,1,300,0),
(7,8890,1,10,0),
(7,10354,1,500,0),
(7,11983,1,300,0),
(7,11984,1,300,0),
(7,11985,1,300,0),
(7,11986,1,300,0),
(7,12524,1,500,0),
(7,12470,1,300,0),
(7,12471,1,300,0),
(7,12472,1,300,0),
(7,12473,1,300,0),
(7,2158,2,1,0),
(7,14548,1,500,0),
(7,9509,1,1,0),
(7,9510,1,1,0),
(7,9511,1,1,0),
(7,9512,1,1,0),
(7,9513,1,1,0),
(7,9514,1,1,0),
(7,9515,1,1,0),
(7,10753,1,1,0),
(7,10754,1,1,0),
(7,10755,1,1,0),
(7,10756,1,1,0),
(7,10757,1,1,0),
(7,10758,1,1,0),
(7,10759,1,1,0),
(7,11296,1,1,0),
(7,11297,1,1,0),
(7,11298,1,1,0),
(7,11299,1,1,0),
(7,11300,1,1,0),
(7,12386,1,1,0),
(7,12387,1,1,0),
(7,12388,1,1,0),
(7,12389,1,1,0),
(7,12390,1,1,0),
(7,13034,1,1,0),
(7,13035,1,1,0),
(7,13036,1,1,0),
(7,13037,1,1,0),
(7,13038,1,1,0),
(7,14179,1,1,0),
(7,14180,1,1,0),
(7,14181,1,1,0),
(7,14182,1,1,0),
(7,14183,1,1,0),
(7,13422,1,1,0),
(7,13423,1,1,0),
(7,13424,1,1,0),
(7,13425,1,1,0),
(7,13426,1,1,0),
(7,13427,1,1,0),
(7,9796,1,3,0),
(7,9700,1,3,0),
(7,10380,1,3,0),
(7,10810,1,3,0),
(7,10811,1,3,0),
(7,11436,1,3,0),
(7,9509,1,1,0),
(7,9510,1,1,0),
(7,9511,1,1,0),
(7,9512,1,1,0),
(7,9513,1,1,0),
(7,9514,1,1,0),
(7,9515,1,1,0),
(7,10753,1,1,0),
(7,10754,1,1,0),
(7,10755,1,1,0),
(7,10756,1,1,0),
(7,10757,1,1,0),
(7,10758,1,1,0),
(7,10759,1,1,0),
(7,11296,1,1,0),
(7,11297,1,1,0),
(7,11298,1,1,0),
(7,11299,1,1,0),
(7,11300,1,1,0),
(7,12509,1,3,0),
(7,12386,1,1,0),
(7,12387,1,1,0),
(7,12388,1,1,0),
(7,12389,1,1,0),
(7,12390,1,1,0),
(7,12872,1,3,0),
(7,12873,1,3,0),
(7,12840,1,1,0),
(7,12841,1,1,0),
(7,12874,1,1,0),
(7,12875,1,1,0),
(7,13191,1,3,0),
(7,13177,1,3,0),
(7,13326,1,3,0),
(7,13034,1,1,0),
(7,13035,1,1,0),
(7,13036,1,1,0),
(7,13037,1,1,0),
(7,13038,1,1,0),
(7,13178,1,3,0),
(7,13453,1,3,0),
(7,13449,1,3,0),
(7,13450,1,3,0),
(7,13404,1,3,0),
(7,13422,1,1,0),
(7,13423,1,1,0),
(7,13424,1,1,0),
(7,13425,1,1,0),
(7,13426,1,1,0),
(7,13427,1,1,0),
(7,13791,1,3,0),
(7,14006,1,3,0),
(7,14031,1,3,0),
(7,14032,1,3,0),
(7,13960,1,3,0),
(7,14029,1,3,0),
(7,13956,1,1,0),
(7,13958,1,1,0),
(7,13957,1,1,0),
(7,13959,1,1,0),
(7,13790,1,3,0),
(7,14005,1,3,0),
(7,14010,1,3,0),
(7,14009,1,3,0),
(7,14008,1,3,0),
(7,13965,1,3,0),
(7,14028,1,3,0),
(7,13963,1,3,0),
(7,14026,1,3,0),
(7,13964,1,3,0),
(7,14027,1,3,0),
(7,14069,1,3,0),
(7,14124,1,3,0),
(7,14065,1,1,0),
(7,14066,1,1,0),
(7,14067,1,1,0),
(7,14068,1,1,0),
(7,13962,1,3,0),
(7,14125,1,3,0),
(7,14089,1,3,0),
(7,14090,1,3,0),
(7,14091,1,3,0),
(7,14092,1,3,0),
(7,14194,1,3,0),
(7,14191,1,3,0),
(7,14198,1,3,0),
(7,14197,1,3,0),
(7,14179,1,1,0),
(7,14180,1,1,0),
(7,14181,1,1,0),
(7,14182,1,1,0),
(7,14183,1,1,0),
(7,14196,1,3,0),
(7,14195,1,3,0),
(7,14193,1,3,0),
(7,14192,1,3,0),
(7,14407,1,3,0),
(7,14414,1,3,0),
(7,14406,1,3,0),
(7,14413,1,3,0),
(7,14416,1,3,0),
(7,14549,1,3,0),
(7,14550,1,3,0),
(7,14502,1,3,0),
(7,14507,1,3,0),
(7,14501,1,3,0),
(7,14506,1,3,0),
(7,14500,1,3,0),
(7,14505,1,3,0),
(7,14498,1,3,0),
(7,14659,1,3,0),
(7,14660,1,3,0),
(7,14657,1,1,0),
(7,14658,1,1,0),
(7,11420,1,3,0),
(7,14704,1,3,0),
(7,11288,1,1,0),
(7,11289,1,1,0),
(7,11290,1,1,0),
(7,11291,1,1,0),
(7,10750,1,3,0),
(7,14705,1,3,0),
(7,10633,1,1,0),
(7,10634,1,1,0),
(7,10635,1,1,0),
(7,10636,1,1,0),
(7,14662,1,3,0),
(7,14663,1,3,0),
(7,14665,1,3,0),
(7,14666,1,3,0),
(7,14667,1,3,0),
(7,14668,1,3,0),
(7,14669,1,3,0),
(7,14670,1,3,0),
(7,14671,1,3,0),
(7,14672,1,3,0),
(7,14673,1,3,0),
(7,14674,1,3,0),
(7,14675,1,3,0),
(7,14676,1,3,0),
(7,14677,1,3,0),
(7,14678,1,3,0),
(7,14679,1,3,0),
(7,14680,1,3,0),
(7,14681,1,3,0),
(7,14682,1,3,0),
(7,14683,1,3,0),
(7,14684,1,3,0),
(7,14685,1,3,0),
(7,14686,1,3,0),
(7,14687,1,3,0),
(7,14688,1,3,0),
(7,14689,1,3,0),
(7,14690,1,3,0),
(7,14691,1,3,0),
(7,14692,1,3,0),
(7,14693,1,3,0),
(7,14694,1,3,0),
(7,14695,1,3,0),
(7,14696,1,3,0),
(7,14697,1,3,0),
(7,14698,1,3,0),
(7,14699,1,3,0),
(7,14700,1,3,0),
(7,14314,1,3,0),
(7,14503,1,3,0),
(7,14510,1,3,0),
(7,14904,1,3,0),
(7,14906,1,3,0),
(7,14910,1,1,0),
(7,14912,1,1,0),
(7,14905,1,3,0),
(7,14907,1,3,0),
(7,14911,1,1,0),
(7,14909,1,1,0),
(7,14855,1,3,0),
(7,14894,1,3,0),
(7,14913,1,3,0),
(7,14914,1,3,0),
(7,14891,1,3,0),
(7,14895,1,3,0),
(7,15027,1,3,0),
(7,15028,1,3,0),
(7,15026,1,1,0),
(7,15025,1,1,0),
(7,15024,1,1,0),
(7,15023,1,1,0),
(7,15064,1,3,0),
(7,15065,1,3,0),
(7,15030,1,3,0),
(7,15031,1,3,0),
(7,15062,1,3,0),
(7,15063,1,3,0),
(7,15066,1,3,0),
(7,15067,1,3,0),
(7,15061,1,3,0),
(7,15060,1,3,0),
(7,1227,1,2,0),
(7,13176,1,2,0),
(7,4360,1,2,0),
(7,4358,1,1,0),
(7,15118,1,3,0),
(7,15119,1,3,0),
(7,15113,1,3,0),
(7,15114,1,3,0),
(7,15115,1,3,0),
(7,15116,1,3,0),
(7,15220,1,3,0),
(7,15221,1,3,0),
(7,14126,1,3,0),
(7,15222,1,3,0),
(7,15223,1,3,0),
(7,15224,1,3,0),
(7,15225,1,3,0),
(7,15524,1,3,0),
(7,15525,1,3,0),
(7,15507,1,3,0),
(7,15508,1,3,0),
(7,15285,1,3,0),
(7,15286,1,3,0),
(7,15281,1,1,0),
(7,15282,1,1,0),
(7,15283,1,1,0),
(7,15284,1,1,0),
(7,15776,1,3,0),
(7,15777,1,3,0),
(7,15774,1,3,0),
(7,15775,1,3,0),
(7,15823,1,3,0),
(7,15824,1,3,0),
(7,15343,1,3,0),
(7,15342,1,3,0),
(7,15341,1,3,0),
(7,15340,1,3,0),
(7,15339,1,3,0),
(7,15338,1,3,0),
(7,15337,1,3,0),
(7,15336,1,3,0),
(7,15335,1,3,0),
(7,15334,1,3,0),
(7,15333,1,3,0),
(7,15332,1,3,0),
(7,15331,1,3,0),
(7,15330,1,3,0),
(7,15329,1,3,0),
(7,15328,1,3,0),
(7,15327,1,3,0),
(7,15326,1,3,0),
(7,15325,1,3,0),
(7,15324,1,3,0),
(7,15323,1,3,0),
(7,15322,1,3,0),
(7,15321,1,3,0),
(7,15314,1,3,0),
(7,15312,1,3,0),
(7,15311,1,3,0),
(7,15306,1,3,0),
(7,15307,1,3,0),
(7,15308,1,3,0),
(7,15309,1,3,0),
(7,15310,1,3,0),
(7,15305,1,3,0),
(7,15304,1,3,0),
(7,15303,1,3,0),
(7,15302,1,3,0),
(7,15301,1,3,0),
(7,15300,1,3,0),
(7,15299,1,3,0),
(7,15298,1,3,0),
(7,15297,1,3,0),
(7,15296,1,3,0),
(7,15295,1,3,0),
(7,15293,1,3,0),
(7,15294,1,3,0),
(7,15292,1,3,0),
(7,15291,1,3,0),
(7,15290,1,3,0),
(7,15289,1,3,0),
(7,15315,1,3,0),
(7,15316,1,3,0),
(7,15317,1,3,0),
(7,15318,1,3,0),
(7,15319,1,3,0),
(7,15320,1,3,0),
(7,15819,1,3,0),
(7,15820,1,3,0),
(7,15821,1,3,0),
(7,15822,1,3,0),
(7,16450,1,3,0),
(7,16451,1,3,0),
(7,16459,1,1,0),
(7,16460,1,1,0),
(7,16461,1,1,0),
(7,16462,1,1,0),
(7,16463,1,1,0),
(7,16464,1,1,0),
(7,16465,1,1,0),
(7,16466,1,1,0),
(7,16467,1,1,0),
(7,16468,1,1,0),
(7,16469,1,1,0),
(7,16470,1,1,0),
(7,16471,1,1,0),
(7,16472,1,1,0),
(7,16454,1,3,0),
(7,16455,1,3,0),
(7,16442,1,3,0),
(7,16443,1,3,0),
(7,16342,1,3,0),
(7,16343,1,3,0),
(7,16444,1,3,0),
(7,16445,1,3,0),
(7,16344,1,3,0),
(7,16345,1,3,0),
(7,16352,1,3,0),
(7,16353,1,3,0),
(7,16446,1,3,0),
(7,16447,1,3,0),
(7,16448,1,3,0),
(7,16449,1,3,0),
(7,16348,1,3,0),
(7,16349,1,3,0);
END;

View File

@@ -0,0 +1,12 @@
BEGIN;
INSERT INTO public.shop_items
(shop_type, shop_id, item_id, cost, quantity, min_hr, min_sr, min_gr, store_level, max_quantity, road_floors, road_fatalis)
VALUES
(5,5,16516,100,1,0,0,1,0,0,0,0),
(5,5,16517,100,1,0,0,1,0,0,0,0),
(7,0,13190,10,1,0,0,0,0,0,0,0),
(7,0,1662,10,1,0,0,0,0,0,0,0),
(7,0,10179,100,1,0,0,0,0,0,0,0);
END;

View File

@@ -1,54 +0,0 @@
package mhfcid
import (
"math"
)
// ConvertCID converts a MHF Character ID String to integer
//
// Banned characters: 0, I, O, S
func ConvertCID(ID string) (r uint32) {
if len(ID) != 6 {
return
}
m := map[rune]uint32{
'1': 0,
'2': 1,
'3': 2,
'4': 3,
'5': 4,
'6': 5,
'7': 6,
'8': 7,
'9': 8,
'A': 9,
'B': 10,
'C': 11,
'D': 12,
'E': 13,
'F': 14,
'G': 15,
'H': 16,
'J': 17,
'K': 18,
'L': 19,
'M': 20,
'N': 21,
'P': 22,
'Q': 23,
'R': 24,
'T': 25,
'U': 26,
'V': 27,
'W': 28,
'X': 29,
'Y': 30,
'Z': 31,
}
for i, c := range ID {
r += m[c] * uint32(math.Pow(32, float64(i)))
}
return
}

View File

@@ -1,7 +1,6 @@
package mhfcourse
import (
_config "erupe-ce/config"
"math"
"sort"
"time"
@@ -67,15 +66,12 @@ func CourseExists(ID uint16, c []Course) bool {
// GetCourseStruct returns a slice of Course(s) from a rights integer
func GetCourseStruct(rights uint32) ([]Course, uint32) {
var resp []Course
for _, c := range _config.ErupeConfig.DefaultCourses {
resp = append(resp, Course{ID: c})
}
resp := []Course{{ID: 1}, {ID: 23}, {ID: 24}}
s := Courses()
sort.Slice(s, func(i, j int) bool {
return s[i].ID > s[j].ID
})
var normalCafeCourseSet, netcafeCourseSet, hidenCourseSet bool
var normalCafeCourseSet, netcafeCourseSet bool
for _, course := range s {
if rights-course.Value() < 0x80000000 {
switch course.ID {
@@ -92,12 +88,6 @@ func GetCourseStruct(rights uint32) ([]Course, uint32) {
}
netcafeCourseSet = true
resp = append(resp, Course{ID: 30})
case 10:
if hidenCourseSet {
break
}
hidenCourseSet = true
resp = append(resp, Course{ID: 31})
}
course.Expiry = time.Date(2030, 1, 1, 0, 0, 0, 0, time.FixedZone("UTC+9", 9*60*60))
resp = append(resp, course)

View File

@@ -1,175 +0,0 @@
package mhfitem
import (
"erupe-ce/common/byteframe"
"erupe-ce/common/token"
_config "erupe-ce/config"
)
type MHFItem struct {
ItemID uint16
}
type MHFSigilEffect struct {
ID uint16
Level uint16
}
type MHFSigil struct {
Effects []MHFSigilEffect
Unk0 uint8
Unk1 uint8
Unk2 uint8
Unk3 uint8
}
type MHFEquipment struct {
WarehouseID uint32
ItemType uint8
Unk0 uint8
ItemID uint16
Level uint16
Decorations []MHFItem
Sigils []MHFSigil
Unk1 uint16
}
type MHFItemStack struct {
WarehouseID uint32
Item MHFItem
Quantity uint16
Unk0 uint32
}
func ReadWarehouseItem(bf *byteframe.ByteFrame) MHFItemStack {
var item MHFItemStack
item.WarehouseID = bf.ReadUint32()
if item.WarehouseID == 0 {
item.WarehouseID = token.RNG.Uint32()
}
item.Item.ItemID = bf.ReadUint16()
item.Quantity = bf.ReadUint16()
item.Unk0 = bf.ReadUint32()
return item
}
func DiffItemStacks(o []MHFItemStack, u []MHFItemStack) []MHFItemStack {
// o = old, u = update, f = final
var f []MHFItemStack
for _, uItem := range u {
exists := false
for i := range o {
if o[i].WarehouseID == uItem.WarehouseID {
exists = true
o[i].Quantity = uItem.Quantity
}
}
if !exists {
uItem.WarehouseID = token.RNG.Uint32()
f = append(f, uItem)
}
}
for _, oItem := range o {
if oItem.Quantity > 0 {
f = append(f, oItem)
}
}
return f
}
func (is MHFItemStack) ToBytes() []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint32(is.WarehouseID)
bf.WriteUint16(is.Item.ItemID)
bf.WriteUint16(is.Quantity)
bf.WriteUint32(is.Unk0)
return bf.Data()
}
func SerializeWarehouseItems(i []MHFItemStack) []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint16(uint16(len(i)))
bf.WriteUint16(0) // Unused
for _, j := range i {
bf.WriteBytes(j.ToBytes())
}
return bf.Data()
}
func ReadWarehouseEquipment(bf *byteframe.ByteFrame) MHFEquipment {
var equipment MHFEquipment
equipment.Decorations = make([]MHFItem, 3)
equipment.Sigils = make([]MHFSigil, 3)
for i := 0; i < 3; i++ {
equipment.Sigils[i].Effects = make([]MHFSigilEffect, 3)
}
equipment.WarehouseID = bf.ReadUint32()
if equipment.WarehouseID == 0 {
equipment.WarehouseID = token.RNG.Uint32()
}
equipment.ItemType = bf.ReadUint8()
equipment.Unk0 = bf.ReadUint8()
equipment.ItemID = bf.ReadUint16()
equipment.Level = bf.ReadUint16()
for i := 0; i < 3; i++ {
equipment.Decorations[i].ItemID = bf.ReadUint16()
}
if _config.ErupeConfig.RealClientMode >= _config.G1 {
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
equipment.Sigils[i].Effects[j].ID = bf.ReadUint16()
}
for j := 0; j < 3; j++ {
equipment.Sigils[i].Effects[j].Level = bf.ReadUint16()
}
equipment.Sigils[i].Unk0 = bf.ReadUint8()
equipment.Sigils[i].Unk1 = bf.ReadUint8()
equipment.Sigils[i].Unk2 = bf.ReadUint8()
equipment.Sigils[i].Unk3 = bf.ReadUint8()
}
}
if _config.ErupeConfig.RealClientMode >= _config.Z1 {
equipment.Unk1 = bf.ReadUint16()
}
return equipment
}
func (e MHFEquipment) ToBytes() []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint32(e.WarehouseID)
bf.WriteUint8(e.ItemType)
bf.WriteUint8(e.Unk0)
bf.WriteUint16(e.ItemID)
bf.WriteUint16(e.Level)
for i := 0; i < 3; i++ {
bf.WriteUint16(e.Decorations[i].ItemID)
}
if _config.ErupeConfig.RealClientMode >= _config.G1 {
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
bf.WriteUint16(e.Sigils[i].Effects[j].ID)
}
for j := 0; j < 3; j++ {
bf.WriteUint16(e.Sigils[i].Effects[j].Level)
}
bf.WriteUint8(e.Sigils[i].Unk0)
bf.WriteUint8(e.Sigils[i].Unk1)
bf.WriteUint8(e.Sigils[i].Unk2)
bf.WriteUint8(e.Sigils[i].Unk3)
}
}
if _config.ErupeConfig.RealClientMode >= _config.Z1 {
bf.WriteUint16(e.Unk1)
}
return bf.Data()
}
func SerializeWarehouseEquipment(i []MHFEquipment) []byte {
bf := byteframe.NewByteFrame()
bf.WriteUint16(uint16(len(i)))
bf.WriteUint16(0) // Unused
for _, j := range i {
bf.WriteBytes(j.ToBytes())
}
return bf.Data()
}

View File

@@ -1,366 +0,0 @@
package mhfmon
const (
Mon0 = iota
Rathian
Fatalis
Kelbi
Mosswine
Bullfango
YianKutKu
LaoShanLung
Cephadrome
Felyne
VeggieElder
Rathalos
Aptonoth
Genprey
Diablos
Khezu
Velociprey
Gravios
Mon18
Vespoid
Gypceros
Plesioth
Basarios
Melynx
Hornetaur
Apceros
Monoblos
Velocidrome
Gendrome
Mon29
Ioprey
Iodrome
Mon32
Kirin
Cephalos
Giaprey
CrimsonFatalis
PinkRathian
BlueYianKutKu
PurpleGypceros
YianGaruga
SilverRathalos
GoldRathian
BlackDiablos
WhiteMonoblos
RedKhezu
GreenPlesioth
BlackGravios
DaimyoHermitaur
AzureRathalos
AshenLaoShanLung
Blangonga
Congalala
Rajang
KushalaDaora
ShenGaoren
GreatThunderbug
Shakalaka
YamaTsukami
Chameleos
RustedKushalaDaora
Blango
Conga
Remobra
Lunastra
Teostra
Hermitaur
ShogunCeanataur
Bulldrome
Anteka
Popo
WhiteFatalis
Mon72
Ceanataur
Hypnocatrice
Lavasioth
Tigrex
Akantor
BrightHypnoc
RedLavasioth
Espinas
BurningEspinas
WhiteHypnoc
AqraVashimu
AqraJebia
Berukyurosu
Mon86
Mon87
Mon88
Pariapuria
PearlEspinas
KamuOrugaron
NonoOrugaron
Raviente
Dyuragaua
Doragyurosu
Gurenzeburu
Burukku
Erupe
Rukodiora
Unknown
Gogomoa
Kokomoa
TaikunZamuza
Abiorugu
Kuarusepusu
Odibatorasu
Disufiroa
Rebidiora
Anorupatisu
Hyujikiki
Midogaron
Giaorugu
MiRu
Farunokku
Pokaradon
Shantien
Pokara
Mon118
Goruganosu
Aruganosu
Baruragaru
Zerureusu
Gougarf
Uruki
Forokururu
Meraginasu
Diorex
GarubaDaora
Inagami
Varusaburosu
Poborubarumu
Block1Duremudira
Mon133
Mon134
Mon135
Mon136
Mon137
Mon138
Gureadomosu
Harudomerugu
Toridcless
Gasurabazura
Kusubami
YamaKurai
Block2Duremudira
Zinogre
Deviljho
Brachydios
BerserkRaviente
ToaTesukatora
Barioth
Uragaan
StygianZinogre
Guanzorumu
SavageDeviljho
Mon156
Egyurasu
Voljang
Nargacuga
Keoaruboru
Zenaserisu
GoreMagala
BlinkingNargacuga
ShagaruMagala
Amatsu
Eruzerion
MusouDuremudira
Mon168
Seregios
Bogabadorumu
Mon171
MusouBogabadorumu
CostumedUruki
MusouZerureusu
Rappy
KingShakalaka
)
type Monster struct {
Name string
Large bool
}
var Monsters = []Monster{
{"Mon0", false},
{"Rathian", true},
{"Fatalis", true},
{"Kelbi", false},
{"Mosswine", false},
{"Bullfango", false},
{"Yian Kut-Ku", true},
{"Lao-Shan Lung", true},
{"Cephadrome", true},
{"Felyne", false},
{"Veggie Elder", false},
{"Rathalos", true},
{"Aptonoth", false},
{"Genprey", false},
{"Diablos", true},
{"Khezu", true},
{"Velociprey", false},
{"Gravios", true},
{"Mon18", false},
{"Vespoid", false},
{"Gypceros", true},
{"Plesioth", true},
{"Basarios", true},
{"Melynx", false},
{"Hornetaur", false},
{"Apceros", false},
{"Monoblos", true},
{"Velocidrome", true},
{"Gendrome", true},
{"Mon29", false},
{"Ioprey", false},
{"Iodrome", true},
{"Mon32", false},
{"Kirin", true},
{"Cephalos", false},
{"Giaprey", false},
{"Crimson Fatalis", true},
{"Pink Rathian", true},
{"Blue Yian Kut-Ku", true},
{"Purple Gypceros", true},
{"Yian Garuga", true},
{"Silver Rathalos", true},
{"Gold Rathian", true},
{"Black Diablos", true},
{"White Monoblos", true},
{"Red Khezu", true},
{"Green Plesioth", true},
{"Black Gravios", true},
{"Daimyo Hermitaur", true},
{"Azure Rathalos", true},
{"Ashen Lao-Shan Lung", true},
{"Blangonga", true},
{"Congalala", true},
{"Rajang", true},
{"Kushala Daora", true},
{"Shen Gaoren", true},
{"Great Thunderbug", false},
{"Shakalaka", false},
{"Yama Tsukami", true},
{"Chameleos", true},
{"Rusted Kushala Daora", true},
{"Blango", false},
{"Conga", false},
{"Remobra", false},
{"Lunastra", true},
{"Teostra", true},
{"Hermitaur", false},
{"Shogun Ceanataur", true},
{"Bulldrome", true},
{"Anteka", false},
{"Popo", false},
{"White Fatalis", true},
{"Mon72", false},
{"Ceanataur", false},
{"Hypnocatrice", true},
{"Lavasioth", true},
{"Tigrex", true},
{"Akantor", true},
{"Bright Hypnocatrice", true},
{"Red Lavasioth", true},
{"Espinas", true},
{"Burning Espinas", true},
{"White Hypnocatrice", true},
{"Aqra Vashimu", true},
{"Aqra Jebia", true},
{"Berukyurosu", true},
{"Mon86", false},
{"Mon87", false},
{"Mon88", false},
{"Pariapuria", true},
{"Pearl Espinas", true},
{"Kamu Orugaron", true},
{"Nono Orugaron", true},
{"Raviente", true}, // + Violent
{"Dyuragaua", true},
{"Doragyurosu", true},
{"Gurenzeburu", true},
{"Burukku", false},
{"Erupe", false},
{"Rukodiora", true},
{"Unknown", true},
{"Gogomoa", true},
{"Kokomoa", false},
{"Taikun Zamuza", true},
{"Abiorugu", true},
{"Kuarusepusu", true},
{"Odibatorasu", true},
{"Disufiroa", true},
{"Rebidiora", true},
{"Anorupatisu", true},
{"Hyujikiki", true},
{"Midogaron", true},
{"Giaorugu", true},
{"Mi-Ru", true}, // + Musou
{"Farunokku", true},
{"Pokaradon", true},
{"Shantien", true},
{"Pokara", false},
{"Mon118", false},
{"Goruganosu", true},
{"Aruganosu", true},
{"Baruragaru", true},
{"Zerureusu", true},
{"Gougarf", true}, // Both
{"Uruki", false},
{"Forokururu", true},
{"Meraginasu", true},
{"Diorex", true},
{"Garuba Daora", true},
{"Inagami", true},
{"Varusablos", true},
{"Poborubarumu", true},
{"1st Block Duremudira", true},
{"Mon133", false},
{"Mon134", false},
{"Mon135", false},
{"Mon136", false},
{"Mon137", false},
{"Mon138", false},
{"Gureadomosu", true},
{"Harudomerugu", true},
{"Toridcless", true},
{"Gasurabazura", true},
{"Kusubami", false},
{"Yama Kurai", true},
{"2nd Block Duremudira", true},
{"Zinogre", true},
{"Deviljho", true},
{"Brachydios", true},
{"Berserk Raviente", true},
{"Toa Tesukatora", true},
{"Barioth", true},
{"Uragaan", true},
{"Stygian Zinogre", true},
{"Guanzorumu", true},
{"Savage Deviljho", true}, // + Starving/Heavenly
{"Mon156", false},
{"Egyurasu", false},
{"Voljang", true},
{"Nargacuga", true},
{"Keoaruboru", true},
{"Zenaserisu", true},
{"Gore Magala", true},
{"Blinking Nargacuga", true},
{"Shagaru Magala", true},
{"Amatsu", true},
{"Eruzerion", true}, // + Musou
{"Musou Duremudira", true},
{"Mon168", false},
{"Seregios", true},
{"Bogabadorumu", true},
{"Mon171", false},
{"Musou Bogabadorumu", true},
{"Costumed Uruki", false},
{"Musou Zerureusu", true},
{"Rappy", false},
{"King Shakalaka", false},
}

View File

@@ -6,12 +6,13 @@ import (
// StringStack is a basic LIFO "stack" for storing strings.
type StringStack struct {
stack []string
Locked bool
stack []string
}
// New creates a new instance of StringStack
func New() *StringStack {
return &StringStack{}
return &StringStack{Locked: false}
}
// Set sets up a new StringStack
@@ -19,6 +20,20 @@ func (s *StringStack) Set(v string) {
s.stack = []string{v}
}
// Lock freezes the StringStack
func (s *StringStack) Lock() {
if !s.Locked {
s.Locked = true
}
}
// Unlock unfreezes the StringStack
func (s *StringStack) Unlock() {
if s.Locked {
s.Locked = false
}
}
// Push pushes a string onto the stack.
func (s *StringStack) Push(v string) {
s.stack = append(s.stack, v)
@@ -26,12 +41,11 @@ func (s *StringStack) Push(v string) {
// Pop pops a string from the stack.
func (s *StringStack) Pop() (string, error) {
var x string
if len(s.stack) == 0 {
return x, errors.New("no items on stack")
return "", errors.New("no items on stack")
}
x = s.stack[len(s.stack)-1]
x := s.stack[len(s.stack)-1]
s.stack = s.stack[:len(s.stack)-1]
return x, nil

View File

@@ -69,7 +69,7 @@ func CSVRemove(csv string, v int) string {
func CSVContains(csv string, v int) bool {
s := strings.Split(csv, ",")
for i := 0; i < len(s); i++ {
j, _ := strconv.ParseInt(s[i], 10, 32)
j, _ := strconv.ParseInt(s[i], 10, 64)
if int(j) == v {
return true
}
@@ -92,7 +92,7 @@ func CSVElems(csv string) []int {
}
s := strings.Split(csv, ",")
for i := 0; i < len(s); i++ {
j, _ := strconv.ParseInt(s[i], 10, 32)
j, _ := strconv.ParseInt(s[i], 10, 64)
r = append(r, int(j))
}
return r

View File

@@ -5,19 +5,18 @@ import (
"time"
)
var RNG = NewRNG()
// Generate returns an alphanumeric token of specified length
func Generate(length int) string {
rng := RNG()
var chars = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
b := make([]rune, length)
for i := range b {
b[i] = chars[RNG.Intn(len(chars))]
b[i] = chars[rng.Intn(len(chars))]
}
return string(b)
}
// NewRNG returns a new NewRNG generator
func NewRNG() *rand.Rand {
// RNG returns a new RNG generator
func RNG() *rand.Rand {
return rand.New(rand.NewSource(time.Now().UnixNano()))
}

View File

@@ -9,95 +9,59 @@
],
"PatchServerManifest": "",
"PatchServerFile": "",
"Screenshots":{
"Enabled":true,
"Host":"127.0.0.1",
"Port":8080,
"OutputDir":"screenshots",
"UploadQuality":100
},
"ScreenshotAPIURL": "",
"DeleteOnSaveCorruption": false,
"ClientMode": "ZZ",
"QuestCacheExpiry": 300,
"CommandPrefix": "!",
"AutoCreateAccount": true,
"DefaultCourses": [1, 23, 24],
"EarthStatus": 0,
"EarthID": 0,
"EarthMonsters": [0, 0, 0, 0],
"SaveDumps": {
"Enabled": true,
"RawEnabled": false,
"OutputDir": "save-backups"
},
"DebugOptions": {
"DevMode": true,
"DevModeOptions": {
"AutoCreateAccount": true,
"CleanDB": false,
"MaxLauncherHR": false,
"LogInboundMessages": false,
"LogOutboundMessages": false,
"LogMessageData": false,
"LogInboundMessages": true,
"LogOutboundMessages": true,
"MaxHexdumpLength": 256,
"DivaOverride": 0,
"FestaOverride": -1,
"TournamentOverride": 0,
"DivaEvent": 0,
"FestaEvent": -1,
"TournamentEvent": 0,
"MezFesEvent": true,
"MezFesAlt": false,
"DisableTokenCheck": false,
"QuestTools": false,
"AutoQuestBackport": true,
"ProxyPort": 0,
"CapLink": {
"Values": [51728, 20000, 51729, 1, 20000],
"Key": "",
"Host": "",
"Port": 80
"QuestDebugTools": false,
"EarthStatusOverride": 0,
"EarthIDOverride": 0,
"EarthMonsterOverride": 0,
"SaveDumps": {
"Enabled": true,
"OutputDir": "save-backups"
}
},
"GameplayOptions": {
"MinFeatureWeapons": 0,
"MaxFeatureWeapons": 1,
"FeaturedWeapons": 1,
"MaximumNP": 100000,
"MaximumRP": 50000,
"MaximumFP": 120000,
"TreasureHuntExpiry": 604800,
"DisableLoginBoost": false,
"DisableBoostTime": false,
"BoostTimeDuration": 7200,
"ClanMealDuration": 3600,
"ClanMemberLimits": [[0, 30], [3, 40], [7, 50], [10, 60]],
"BoostTimeDuration": 120,
"GuildMealDuration": 60,
"BonusQuestAllowance": 3,
"DailyQuestAllowance": 1,
"MezfesSoloTickets": 10,
"MezfesGroupTickets": 4,
"LowLatencyRaviente": false,
"RegularRavienteMaxPlayers": 8,
"ViolentRavienteMaxPlayers": 8,
"BerserkRavienteMaxPlayers": 32,
"ExtremeRavienteMaxPlayers": 32,
"SmallBerserkRavienteMaxPlayers": 8,
"GUrgentRate": 0.10,
"GUrgentRate": 10,
"GCPMultiplier": 1.00,
"HRPMultiplier": 1.00,
"HRPMultiplierNC": 1.00,
"SRPMultiplier": 1.00,
"SRPMultiplierNC": 1.00,
"GRPMultiplier": 1.00,
"GRPMultiplierNC": 1.00,
"GSRPMultiplier": 1.00,
"GSRPMultiplierNC": 1.00,
"ZennyMultiplier": 1.00,
"ZennyMultiplierNC": 1.00,
"GZennyMultiplier": 1.00,
"GZennyMultiplierNC": 1.00,
"MaterialMultiplier": 1.00,
"MaterialMultiplierNC": 1.00,
"GMaterialMultiplier": 1.00,
"GMaterialMultiplierNC": 1.00,
"ExtraCarves": 0,
"ExtraCarvesNC": 0,
"GExtraCarves": 0,
"GExtraCarvesNC": 0,
"DisableHunterNavi": false,
"MezFesSoloTickets": 5,
"MezFesGroupTickets": 1,
"MezFesDuration": 172800,
"MezFesSwitchMinigame": false,
"EnableKaijiEvent": false,
"EnableHiganjimaEvent": false,
"EnableNierEvent": false,
@@ -107,68 +71,37 @@
"Discord": {
"Enabled": false,
"BotToken": "",
"RelayChannel": {
"Enabled": false,
"MaxMessageLength": 183,
"RelayChannelID": ""
}
"RealtimeChannelID": ""
},
"Commands": [
{
"Name": "Help",
"Enabled": true,
"Description": "Show enabled chat commands",
"Prefix": "help"
}, {
"Name": "Rights",
"Enabled": false,
"Description": "Overwrite the Rights value on your account",
"Prefix": "rights"
}, {
"Name": "Raviente",
"Enabled": true,
"Description": "Various Raviente siege commands",
"Prefix": "ravi"
}, {
"Name": "Teleport",
"Enabled": false,
"Description": "Teleport to specified coordinates",
"Prefix": "tele"
}, {
"Name": "Reload",
"Enabled": true,
"Description": "Reload all players in your Land",
"Prefix": "reload"
}, {
"Name": "KeyQuest",
"Enabled": false,
"Description": "Overwrite your HR Key Quest progress",
"Prefix": "kqf"
}, {
"Name": "Course",
"Enabled": true,
"Description": "Toggle Courses on your account",
"Prefix": "course"
}, {
"Name": "PSN",
"Enabled": true,
"Description": "Link a PlayStation Network ID to your account",
"Prefix": "psn"
}, {
"Name": "Discord",
"Enabled": true,
"Description": "Generate a token to link your Discord account",
"Prefix": "discord"
}, {
"Name": "Ban",
"Enabled": false,
"Description": "Ban/Temp Ban a user",
"Prefix": "ban"
}, {
"Name": "Timer",
"Enabled": true,
"Description": "Toggle the Quest timer",
"Prefix": "timer"
}
],
"Courses": [
@@ -195,13 +128,9 @@
"Enabled": true,
"Port": 53312
},
"API": {
"Enabled": true,
"Port": 8080,
"PatchServer": "",
"Banners": [],
"Messages": [],
"Links": []
"SignV2": {
"Enabled": false,
"Port": 8080
},
"Channel": {
"Enabled": true

View File

@@ -58,7 +58,7 @@ const (
)
var versionStrings = []string{"S1.0", "S1.5", "S2.0", "S2.5", "S3.0", "S3.5", "S4.0", "S5.0", "S5.5", "S6.0", "S7.0",
"S8.0", "S8.5", "S9.0", "S10", "FW.1", "FW.2", "FW.3", "FW.4", "FW.5", "G1", "G2", "G3", "G3.1", "G3.2", "GG", "G5",
"S8.0", "S8.5", "S9", "S10", "FW.1", "FW.2", "FW.3", "FW.4", "FW.5", "G1", "G2", "G3", "G3.1", "G3.2", "GG", "G5",
"G5.1", "G5.2", "G6", "G6.1", "G7", "G8", "G8.1", "G9", "G9.1", "G10", "G10.1", "Z1", "Z2", "ZZ"}
func (m Mode) String() string {
@@ -75,119 +75,78 @@ type Config struct {
LoginNotices []string // MHFML string of the login notices displayed
PatchServerManifest string // Manifest patch server override
PatchServerFile string // File patch server override
ScreenshotAPIURL string // Destination for screenshots uploaded to BBS
DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion
ClientMode string
RealClientMode Mode
QuestCacheExpiry int // Number of seconds to keep quest data cached
CommandPrefix string // The prefix for commands
AutoCreateAccount bool // Automatically create accounts if they don't exist
DefaultCourses []uint16
EarthStatus int32
EarthID int32
EarthMonsters []int32
SaveDumps SaveDumpOptions
Screenshots ScreenshotsOptions
DevMode bool
DebugOptions DebugOptions
DevModeOptions DevModeOptions
GameplayOptions GameplayOptions
Discord Discord
Commands []Command
Courses []Course
Database Database
Sign Sign
API API
SignV2 SignV2
Channel Channel
Entrance Entrance
}
// DevModeOptions holds various debug/temporary options for use while developing Erupe.
type DevModeOptions struct {
AutoCreateAccount bool // Automatically create accounts if they don't exist
CleanDB bool // Automatically wipes the DB on server reset.
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds.
LogInboundMessages bool // Log all messages sent to the server
LogOutboundMessages bool // Log all messages sent to the clients
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
DivaEvent int // Diva Defense event status
FestaEvent int // Hunter's Festa event status
TournamentEvent int // VS Tournament event status
MezFesEvent bool // MezFes status
MezFesAlt bool // Swaps out Volpakkun for Tokotoko
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
QuestDebugTools bool // Enable various quest debug logs
EarthStatusOverride int32
EarthIDOverride int32
EarthMonsterOverride int32
SaveDumps SaveDumpOptions
}
type SaveDumpOptions struct {
Enabled bool
RawEnabled bool
OutputDir string
}
type ScreenshotsOptions struct {
Enabled bool
Host string // Destination for screenshots uploaded to BBS
Port uint32 // Port for screenshots API
OutputDir string
UploadQuality int //Determines the upload quality to the server
}
// DebugOptions holds various debug/temporary options for use while developing Erupe.
type DebugOptions struct {
CleanDB bool // Automatically wipes the DB on server reset.
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds.
LogInboundMessages bool // Log all messages sent to the server
LogOutboundMessages bool // Log all messages sent to the clients
LogMessageData bool // Log all bytes transferred as a hexdump
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
DivaOverride int // Diva Defense event status
FestaOverride int // Hunter's Festa event status
TournamentOverride int // VS Tournament event status
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
QuestTools bool // Enable various quest debug logs
AutoQuestBackport bool // Automatically backport quest files
ProxyPort uint16 // Forces the game to connect to a channel server proxy
CapLink CapLinkOptions
}
type CapLinkOptions struct {
Values []uint16
Key string
Host string
Port int
Enabled bool
OutputDir string
}
// GameplayOptions has various gameplay modifiers
type GameplayOptions struct {
MinFeatureWeapons int // Minimum number of Active Feature weapons to generate daily
MaxFeatureWeapons int // Maximum number of Active Feature weapons to generate daily
MaximumNP int // Maximum number of NP held by a player
MaximumRP uint16 // Maximum number of RP held by a player
MaximumFP uint32 // Maximum number of FP held by a player
TreasureHuntExpiry uint32 // Seconds until a Clan Treasure Hunt will expire
TreasureHuntPartnyaCooldown uint32 // Seconds until a Partnya can be assigned to another Clan Treasure Hunt
DisableLoginBoost bool // Disables the Login Boost system
DisableBoostTime bool // Disables the daily NetCafe Boost Time
BoostTimeDuration int // Second that the NetCafe Boost Time lasts
ClanMealDuration int // Second that a Clan Meal can be activated for after cooking
ClanMemberLimits [][]uint8 // Array of maximum Clan Members -> [Rank, Members]
BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily
DailyQuestAllowance uint32 // Number of Daily Quests to allow daily
LowLatencyRaviente bool // Toggles low latency mode for Raviente, can be network intensive
FeaturedWeapons int // Number of Active Feature weapons to generate daily
MaximumNP int // Maximum number of NP held by a player
MaximumRP uint16 // Maximum number of RP held by a player
MaximumFP uint32 // Maximum number of FP held by a player
DisableLoginBoost bool // Disables the Login Boost system
DisableBoostTime bool // Disables the daily NetCafe Boost Time
BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for
GuildMealDuration int // The number of minutes a Guild Meal can be activated for after cooking
BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily
DailyQuestAllowance uint32 // Number of Daily Quests to allow daily
MezfesSoloTickets uint32 // Number of solo tickets given weekly
MezfesGroupTickets uint32 // Number of group tickets given weekly
LowLatencyRaviente bool // Toggles low latency mode for Raviente, can be network intensive
RegularRavienteMaxPlayers uint8
ViolentRavienteMaxPlayers uint8
BerserkRavienteMaxPlayers uint8
ExtremeRavienteMaxPlayers uint8
SmallBerserkRavienteMaxPlayers uint8
GUrgentRate float32 // Adjusts the rate of G Urgent quests spawning
GUrgentRate uint16 // Adjusts the rate of G Urgent quests spawning
GCPMultiplier float32 // Adjusts the multiplier of GCP rewarded for quest completion
HRPMultiplier float32 // Adjusts the multiplier of Hunter Rank Points rewarded for quest completion
HRPMultiplierNC float32 // Adjusts the multiplier of Hunter Rank Points rewarded for quest completion in a NetCafe
SRPMultiplier float32 // Adjusts the multiplier of Skill Rank Points rewarded for quest completion
SRPMultiplierNC float32 // Adjusts the multiplier of Skill Rank Points rewarded for quest completion in a NetCafe
GRPMultiplier float32 // Adjusts the multiplier of G Rank Points rewarded for quest completion
GRPMultiplierNC float32 // Adjusts the multiplier of G Rank Points rewarded for quest completion in a NetCafe
GSRPMultiplier float32 // Adjusts the multiplier of G Skill Rank Points rewarded for quest completion
GSRPMultiplierNC float32 // Adjusts the multiplier of G Skill Rank Points rewarded for quest completion in a NetCafe
ZennyMultiplier float32 // Adjusts the multiplier of Zenny rewarded for quest completion
ZennyMultiplierNC float32 // Adjusts the multiplier of Zenny rewarded for quest completion in a NetCafe
GZennyMultiplier float32 // Adjusts the multiplier of G Zenny rewarded for quest completion
GZennyMultiplierNC float32 // Adjusts the multiplier of G Zenny rewarded for quest completion in a NetCafe
MaterialMultiplier float32 // Adjusts the multiplier of Monster Materials rewarded for quest completion
MaterialMultiplierNC float32 // Adjusts the multiplier of Monster Materials rewarded for quest completion in a NetCafe
GMaterialMultiplier float32 // Adjusts the multiplier of G Rank Monster Materials rewarded for quest completion
GMaterialMultiplierNC float32 // Adjusts the multiplier of G Rank Monster Materials rewarded for quest completion in a NetCafe
ExtraCarves uint16 // Grant n extra chances to carve ALL carcasses
ExtraCarvesNC uint16 // Grant n extra chances to carve ALL carcasses in a NetCafe
GExtraCarves uint16 // Grant n extra chances to carve ALL G Rank carcasses
GExtraCarvesNC uint16 // Grant n extra chances to carve ALL G Rank carcasses in a NetCafe
DisableHunterNavi bool // Disables the Hunter Navi
MezFesSoloTickets uint32 // Number of solo tickets given weekly
MezFesGroupTickets uint32 // Number of group tickets given weekly
MezFesDuration int // Seconds that MezFes will last for weekly (from 12AM Mon backwards)
MezFesSwitchMinigame bool // Swaps out Volpakkun Together for Tokotoko Partnya
EnableKaijiEvent bool // Enables the Kaiji event in the Rasta Bar
EnableHiganjimaEvent bool // Enables the Higanjima event in the Rasta Bar
EnableNierEvent bool // Enables the Nier event in the Rasta Bar
@@ -197,23 +156,16 @@ type GameplayOptions struct {
// Discord holds the discord integration config.
type Discord struct {
Enabled bool
BotToken string
RelayChannel DiscordRelay
}
type DiscordRelay struct {
Enabled bool
MaxMessageLength int
RelayChannelID string
Enabled bool
BotToken string
RealtimeChannelID string
}
// Command is a channelserver chat command
type Command struct {
Name string
Enabled bool
Description string
Prefix string
Name string
Enabled bool
Prefix string
}
// Course represents a course within MHF
@@ -237,32 +189,10 @@ type Sign struct {
Port int
}
// API holds server config
type API struct {
Enabled bool
Port int
PatchServer string
Banners []APISignBanner
Messages []APISignMessage
Links []APISignLink
}
type APISignBanner struct {
Src string `json:"src"` // Displayed image URL
Link string `json:"link"` // Link accessed on click
}
type APISignMessage struct {
Message string `json:"message"` // Displayed message
Date int64 `json:"date"` // Displayed date
Kind int `json:"kind"` // 0 for 'Default', 1 for 'New'
Link string `json:"link"` // Link accessed on click
}
type APISignLink struct {
Name string `json:"name"` // Displayed name
Icon string `json:"icon"` // Displayed icon. It will be cast as a monochrome color as long as it is transparent.
Link string `json:"link"` // Link accessed on click
// SignV2 holds the new sign server config
type SignV2 struct {
Enabled bool
Port int
}
type Channel struct {
@@ -361,10 +291,6 @@ func LoadConfig() (*Config, error) {
c.RealClientMode = ZZ
}
if c.GameplayOptions.MinFeatureWeapons > c.GameplayOptions.MaxFeatureWeapons {
c.GameplayOptions.MinFeatureWeapons = c.GameplayOptions.MaxFeatureWeapons
}
return c, nil
}

View File

@@ -1,66 +0,0 @@
# Docker for erupe
## Building the container
Run the following from the route of the soruce folder. In this example we give it the tag of dev to seperate it from any other container verions.
```bash
docker build . -t erupe:dev
```
## Running the container in isolation
This is just running the container. You can do volume mounts into the container for the `config.json` to tell it to communicate to a database. You will need to do this also for other folders such as `bin` and `savedata`
```bash
docker run erupe:dev
```
## Docker compose
Docker compose allows you to run multiple containers at once. The docker compose in this folder has 3 things set up.
- postgres
- pg admin (Admin interface to make db changes)
- erupe
We automatically populate the database to the latest version on start. If you you are updating you will need to apply the new schemas manually.
Before we get started you should make sure the database info matches whats in the docker compose file for the environment variables `POSTGRES_PASSWORD`,`POSTGRES_USER` and `POSTGRES_DB`. You can set the host to be the service name `db`.
Here is a example of what you would put in the config.json if you was to leave the defaults. It is strongly recommended to change the password.
```txt
"Database": {
"Host": "db",
"Port": 5432,
"User": "postgres",
"Password": "password",
"Database": "erupe"
},
```
Place this file within ./docker/config.json
You will need to do the same for your bins place these in ./docker/bin
# Setting up the web hosted materials
Clone the Severs repo into ./docker/Severs
Make sure your hosts are pointing to where this is hosted
## Turning off the server safely
```bash
docker-compose stop
```
## Turning off the server destructive
```bash
docker-compose down
```
Make sure if you want to delete your data you delete the folders that persisted
- ./docker/savedata
- ./docker/db-data
## Turning on the server again
This boots the db pgadmin and the server in a detached state
```bash
docker-compose up -d
```
if you want all the logs and you want it to be in an attached state
```bash
docker-compose up
```

View File

@@ -1,71 +0,0 @@
version: "3.9"
# 1. docker-compose up db pgadmin
# 2. Use pgadmin to restore db and also apply patch-schema
# 3. Configure the config.json example. in docker you can point to the service name for the database i.e db
# 4. In seperate terminal docker-compose up server
# 5. If all went well happy hunting!
services:
db:
image: postgres
environment:
# (Make sure these match config.json)
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=erupe
ports:
- "5432:5432"
volumes:
- ./db-data/:/var/lib/postgresql/data/
- ../schemas/:/schemas/
- ./init/setup.sh:/docker-entrypoint-initdb.d/setup.sh
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
pgadmin:
image: dpage/pgadmin4
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: user@pgadmin.com
PGADMIN_DEFAULT_PASSWORD: password
ports:
- "5050:80"
depends_on:
db:
condition: service_healthy
server:
depends_on:
db:
condition: service_healthy
# If using prebuilt container change paths and config
build:
context: ../
volumes:
- ../config.json:/app/erupe/config.json
- ../bin:/app/erupe/bin
- ./savedata:/app/erupe/savedata
ports:
# (Make sure these match config.json)
- "53312:53312" #Sign V1
- "8080:8080" #Sign V2
- "53310:53310" #Entrance
# Channels
- "54001:54001"
- "54002:54002"
- "54003:54003"
- "54004:54004"
- "54005:54005"
- "54006:54006"
- "54007:54007"
- "54008:54008"
web:
image: httpd:latest
container_name: my-apache-app
ports:
- '80:80'
volumes:
- ./Servers:/usr/local/apache2/htdocs
depends_on:
db:
condition: service_healthy

View File

@@ -1,22 +0,0 @@
#!/bin/bash
set -e
echo "INIT!"
pg_restore --username="$POSTGRES_USER" --dbname="$POSTGRES_DB" --verbose /schemas/init.sql
echo "Updating!"
for file in /schemas/update-schema/*
do
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -1 -f $file
done
echo "Patching!"
for file in /schemas/patch-schema/*
do
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -1 -f $file
done

BIN
erupe.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

31
go.mod
View File

@@ -4,35 +4,32 @@ go 1.21
require (
github.com/bwmarrin/discordgo v0.27.1
github.com/gorilla/handlers v1.5.2
github.com/gorilla/mux v1.8.1
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
github.com/jmoiron/sqlx v1.3.5
github.com/lib/pq v1.10.9
github.com/spf13/viper v1.17.0
go.uber.org/zap v1.26.0
golang.org/x/crypto v0.17.0
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/text v0.14.0
github.com/spf13/viper v1.16.0
go.uber.org/zap v1.25.0
golang.org/x/crypto v0.12.0
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
golang.org/x/text v0.12.0
)
require (
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/sys v0.11.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

76
go.sum
View File

@@ -38,6 +38,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY=
github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -49,21 +51,21 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -125,13 +127,13 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -160,34 +162,30 @@ github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRU
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -211,8 +209,8 @@ go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -220,8 +218,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -232,8 +230,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -289,8 +287,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -345,8 +341,9 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -356,8 +353,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -501,9 +498,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

42
main.go
View File

@@ -10,11 +10,11 @@ import (
"syscall"
"time"
"erupe-ce/server/api"
"erupe-ce/server/channelserver"
"erupe-ce/server/discordbot"
"erupe-ce/server/entranceserver"
"erupe-ce/server/signserver"
"erupe-ce/server/signv2server"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
@@ -26,6 +26,7 @@ func cleanDB(db *sqlx.DB) {
_ = db.MustExec("DELETE FROM guild_characters")
_ = db.MustExec("DELETE FROM guilds")
_ = db.MustExec("DELETE FROM characters")
_ = db.MustExec("DELETE FROM sign_sessions")
_ = db.MustExec("DELETE FROM users")
}
@@ -45,7 +46,11 @@ func main() {
var zapLogger *zap.Logger
config := _config.ErupeConfig
zapLogger, _ = zap.NewDevelopment()
if config.DevMode {
zapLogger, _ = zap.NewDevelopment()
} else {
zapLogger, _ = zap.NewProduction()
}
defer zapLogger.Sync()
logger := zapLogger.Named("main")
@@ -91,12 +96,6 @@ func main() {
}
discordBot = bot
_, err = discordBot.Session.ApplicationCommandBulkOverwrite(discordBot.Session.State.User.ID, "", discordbot.Commands)
if err != nil {
preventClose(fmt.Sprintf("Discord: Failed to start, %s", err.Error()))
}
logger.Info("Discord: Started successfully")
} else {
logger.Info("Discord: Disabled")
@@ -125,14 +124,11 @@ func main() {
logger.Info("Database: Started successfully")
// Clear stale data
if config.DebugOptions.ProxyPort == 0 {
_ = db.MustExec("DELETE FROM sign_sessions")
}
_ = db.MustExec("DELETE FROM sign_sessions")
_ = db.MustExec("DELETE FROM servers")
_ = db.MustExec(`UPDATE guild_characters SET treasure_hunt=NULL`)
// Clean the DB if the option is on.
if config.DebugOptions.CleanDB {
if config.DevMode && config.DevModeOptions.CleanDB {
logger.Info("Database: Started clearing...")
cleanDB(db)
logger.Info("Database: Finished clearing")
@@ -181,21 +177,21 @@ func main() {
}
// New Sign server
var ApiServer *api.APIServer
if config.API.Enabled {
ApiServer = api.NewAPIServer(
&api.Config{
var newSignServer *signv2server.Server
if config.SignV2.Enabled {
newSignServer = signv2server.NewServer(
&signv2server.Config{
Logger: logger.Named("sign"),
ErupeConfig: _config.ErupeConfig,
DB: db,
})
err = ApiServer.Start()
err = newSignServer.Start()
if err != nil {
preventClose(fmt.Sprintf("API: Failed to start, %s", err.Error()))
preventClose(fmt.Sprintf("SignV2: Failed to start, %s", err.Error()))
}
logger.Info("API: Started successfully")
logger.Info("SignV2: Started successfully")
} else {
logger.Info("API: Disabled")
logger.Info("SignV2: Disabled")
}
var channels []*channelserver.Server
@@ -273,8 +269,8 @@ func main() {
signServer.Shutdown()
}
if config.API.Enabled {
ApiServer.Shutdown()
if config.SignV2.Enabled {
newSignServer.Shutdown()
}
if config.Entrance.Enabled {

View File

@@ -0,0 +1,10 @@
BEGIN;
DROP TABLE IF EXISTS sign_sessions;
DROP TABLE IF EXISTS characters;
DROP TABLE IF EXISTS users;
DROP DOMAIN IF EXISTS uint8;
DROP DOMAIN IF EXISTS uint16;
END;

View File

@@ -0,0 +1,36 @@
BEGIN;
CREATE DOMAIN uint8 AS smallint
CHECK(VALUE >= 0 AND VALUE <= 255);
CREATE DOMAIN uint16 AS integer
CHECK(VALUE >= 0 AND VALUE <= 65536);
CREATE TABLE users (
id serial NOT NULL PRIMARY KEY,
username text UNIQUE NOT NULL,
password text NOT NULL
);
CREATE TABLE characters (
id serial NOT NULL PRIMARY KEY,
user_id bigint REFERENCES users(id),
is_female boolean,
is_new_character boolean,
small_gr_level uint8,
gr_override_mode boolean,
name varchar(15),
unk_desc_string varchar(31),
gr_override_level uint16,
gr_override_unk0 uint8,
gr_override_unk1 uint8
);
CREATE TABLE sign_sessions (
id serial NOT NULL PRIMARY KEY,
user_id bigint REFERENCES users(id),
auth_token_num bigint,
auth_token_str text
);
END;

View File

@@ -0,0 +1,8 @@
BEGIN;
ALTER TABLE characters
DROP COLUMN exp,
DROP COLUMN weapon,
DROP COLUMN last_login;
END;

View File

@@ -0,0 +1,8 @@
BEGIN;
ALTER TABLE characters
ADD COLUMN exp uint16,
ADD COLUMN weapon uint16,
ADD COLUMN last_login integer;
END;

View File

@@ -0,0 +1,6 @@
BEGIN;
ALTER TABLE characters
DROP COLUMN savedata;
END;

View File

@@ -0,0 +1,6 @@
BEGIN;
ALTER TABLE characters
ADD COLUMN savedata bytea;
END;

View File

@@ -0,0 +1,13 @@
BEGIN;
ALTER TABLE characters
DROP COLUMN decomyset,
DROP COLUMN hunternavi,
DROP COLUMN otomoairou,
DROP COLUMN partner,
DROP COLUMN platebox,
DROP COLUMN platedata,
DROP COLUMN platemyset,
DROP COLUMN rengokudata;
END;

View File

@@ -0,0 +1,13 @@
BEGIN;
ALTER TABLE characters
ADD COLUMN decomyset bytea,
ADD COLUMN hunternavi bytea,
ADD COLUMN otomoairou bytea,
ADD COLUMN partner bytea,
ADD COLUMN platebox bytea,
ADD COLUMN platedata bytea,
ADD COLUMN platemyset bytea,
ADD COLUMN rengokudata bytea;
END;

View File

@@ -0,0 +1,5 @@
BEGIN;
DROP TABLE IF EXISTS questlists;
END;

View File

@@ -0,0 +1,8 @@
BEGIN;
CREATE TABLE questlists (
ind int NOT NULL PRIMARY KEY,
questlist bytea
);
END;

View File

@@ -0,0 +1,6 @@
BEGIN;
ALTER TABLE characters
DROP COLUMN savemercenary;
END;

View File

@@ -0,0 +1,6 @@
BEGIN;
ALTER TABLE characters
ADD COLUMN savemercenary bytea;
END;

View File

@@ -11,8 +11,7 @@ type ChatType uint8
// Chat types
const (
ChatTypeWorld ChatType = 0
ChatTypeStage = 1
ChatTypeLocal ChatType = 1
ChatTypeGuild = 2
ChatTypeAlliance = 3
ChatTypeParty = 4

View File

@@ -0,0 +1,48 @@
package binpacket
import (
"github.com/Andoryuuta/Erupe/network"
"github.com/Andoryuuta/byteframe"
)
type ChatTargetType uint16
const (
CHAT_TARGET_PRIVATE = 0x05
CHAT_TARGET_PARTY = 0x04
)
type MsgBinTargetedChatMessage struct {
// I can't see a reason if this is indeed the number of targets, that
// it should use 2 bytes
TargetCount uint16
TargetCharIDs []uint32
TargetType uint16
RawDataPayload []byte
}
// Opcode returns the ID associated with this packet type.
func (m *MsgBinTargetedChatMessage) Opcode() network.PacketID {
return network.MSG_SYS_CAST_BINARY
}
func (m *MsgBinTargetedChatMessage) Parse(bf *byteframe.ByteFrame) error {
m.TargetCount = bf.ReadUint16()
i := uint16(0)
m.TargetCharIDs = make([]uint32, m.TargetCount)
for ; i < m.TargetCount; i++ {
m.TargetCharIDs[i] = bf.ReadUint32()
}
m.TargetType = bf.ReadUint16()
m.RawDataPayload = bf.DataFromCurrent()
return nil
}
// Build builds a binary packet from the current data.
func (m *MsgBinTargetedChatMessage) Build(bf *byteframe.ByteFrame) error {
panic("Not implemented")
}

View File

@@ -4,10 +4,11 @@ import (
"encoding/hex"
"errors"
_config "erupe-ce/config"
"erupe-ce/network/crypto"
"fmt"
"io"
"net"
"erupe-ce/network/crypto"
)
// CryptConn represents a MHF encrypted two-way connection,
@@ -66,7 +67,7 @@ func (cc *CryptConn) ReadPacket() ([]byte, error) {
cc.readKeyRot = uint32(cph.KeyRotDelta) * (cc.readKeyRot + 1)
}
out, combinedCheck, check0, check1, check2 := crypto.Crypto(encryptedPacketBody, cc.readKeyRot, false, nil)
out, combinedCheck, check0, check1, check2 := crypto.Decrypt(encryptedPacketBody, cc.readKeyRot, nil)
if cph.Check0 != check0 || cph.Check1 != check1 || cph.Check2 != check2 {
fmt.Printf("got c0 %X, c1 %X, c2 %X\n", check0, check1, check2)
fmt.Printf("want c0 %X, c1 %X, c2 %X\n", cph.Check0, cph.Check1, cph.Check2)
@@ -76,7 +77,7 @@ func (cc *CryptConn) ReadPacket() ([]byte, error) {
// Attempt to bruteforce it.
fmt.Println("Crypto out of sync? Attempting bruteforce")
for key := byte(0); key < 255; key++ {
out, combinedCheck, check0, check1, check2 = crypto.Crypto(encryptedPacketBody, 0, false, &key)
out, combinedCheck, check0, check1, check2 = crypto.Decrypt(encryptedPacketBody, 0, &key)
//fmt.Printf("Key: 0x%X\n%s\n", key, hex.Dump(out))
if cph.Check0 == check0 && cph.Check1 == check1 && cph.Check2 == check2 {
fmt.Printf("Bruceforce successful, override key: 0x%X\n", key)
@@ -105,7 +106,7 @@ func (cc *CryptConn) SendPacket(data []byte) error {
}
// Encrypt the data
encData, combinedCheck, check0, check1, check2 := crypto.Crypto(data, cc.sendKeyRot, true, nil)
encData, combinedCheck, check0, check1, check2 := crypto.Encrypt(data, cc.sendKeyRot, nil)
header := &CryptPacketHeader{}
header.Pf0 = byte(((uint(len(encData)) >> 12) & 0xF3) | 3)
@@ -122,7 +123,9 @@ func (cc *CryptConn) SendPacket(data []byte) error {
return err
}
cc.conn.Write(append(headerBytes, encData...))
cc.conn.Write(headerBytes)
cc.conn.Write(encData)
cc.sentPackets++
cc.prevSendPacketCombinedCheck = combinedCheck

View File

@@ -6,30 +6,46 @@ var (
_sharedCryptKey = []byte{0xDD, 0xA8, 0x5F, 0x1E, 0x57, 0xAF, 0xC0, 0xCC, 0x43, 0x35, 0x8F, 0xBB, 0x6F, 0xE6, 0xA1, 0xD6, 0x60, 0xB9, 0x1A, 0xAE, 0x20, 0x49, 0x24, 0x81, 0x21, 0xFE, 0x86, 0x2B, 0x98, 0xB7, 0xB3, 0xD2, 0x91, 0x01, 0x3A, 0x4C, 0x65, 0x92, 0x1C, 0xF4, 0xBE, 0xDD, 0xD9, 0x08, 0xE6, 0x81, 0x98, 0x1B, 0x8D, 0x60, 0xF3, 0x6F, 0xA1, 0x47, 0x24, 0xF1, 0x53, 0x45, 0xC8, 0x7B, 0x88, 0x80, 0x4E, 0x36, 0xC3, 0x0D, 0xC9, 0xD6, 0x8B, 0x08, 0x19, 0x0B, 0xA5, 0xC1, 0x11, 0x4C, 0x60, 0xF8, 0x5D, 0xFC, 0x15, 0x68, 0x7E, 0x32, 0xC0, 0x50, 0xAB, 0x64, 0x1F, 0x8A, 0xD4, 0x08, 0x39, 0x7F, 0xC2, 0xFB, 0xBA, 0x6C, 0xF0, 0xE6, 0xB0, 0x31, 0x10, 0xC1, 0xBF, 0x75, 0x43, 0xBB, 0x18, 0x04, 0x0D, 0xD1, 0x97, 0xF7, 0x23, 0x21, 0x83, 0x8B, 0xCA, 0x25, 0x2B, 0xA3, 0x03, 0x13, 0xEA, 0xAE, 0xFE, 0xF0, 0xEB, 0xFD, 0x85, 0x57, 0x53, 0x65, 0x41, 0x2A, 0x40, 0x99, 0xC0, 0x94, 0x65, 0x7E, 0x7C, 0x93, 0x82, 0xB0, 0xB3, 0xE5, 0xC0, 0x21, 0x09, 0x84, 0xD5, 0xEF, 0x9F, 0xD1, 0x7E, 0xDC, 0x4D, 0xF5, 0x7E, 0xCD, 0x45, 0x3C, 0x7F, 0xF5, 0x59, 0x98, 0xC6, 0x55, 0xFC, 0x9F, 0xA3, 0xB7, 0x74, 0xEE, 0x31, 0x98, 0xE6, 0xB7, 0xBE, 0x26, 0xF4, 0x3C, 0x76, 0xF1, 0x23, 0x7E, 0x02, 0x4E, 0x3C, 0xD1, 0xC7, 0x28, 0x23, 0x73, 0xC4, 0xD9, 0x5E, 0x0D, 0xA1, 0x80, 0xA5, 0xAA, 0x26, 0x0A, 0xA3, 0x44, 0x82, 0x74, 0xE6, 0x3C, 0x44, 0x27, 0x51, 0x0D, 0x5F, 0xC7, 0x9C, 0xD6, 0x63, 0x67, 0xA5, 0x27, 0x97, 0x38, 0xFB, 0x2D, 0xD3, 0xD6, 0x60, 0x25, 0x83, 0x4D, 0x37, 0x5B, 0x40, 0x59, 0x11, 0x77, 0x51, 0x11, 0x14, 0x18, 0x07, 0x63, 0xB1, 0x34, 0x3D, 0xB8, 0x60, 0x13, 0xC2, 0xE8, 0x13, 0x82}
)
// Crypto is a generalized MHF crypto function that can perform both encryption and decryption,
// Encrypt encrypts the given data using MHF's custom encryption+checksum method.
// if a overrideByteKey value is supplied (!= nil), it will be used to override the derived/truncated key byte.
func Encrypt(data []byte, key uint32, overrideByteKey *byte) (outputData []byte, combinedCheck uint16, check0 uint16, check1 uint16, check2 uint16) {
return _generalCrypt(data, key, 0, overrideByteKey)
}
// Decrypt decrypts the given data using MHF's custom decryption+checksum method.
// if a overrideByteKey value is supplied (!= nil), it will be used to override the derived/truncated key byte.
func Decrypt(data []byte, key uint32, overrideByteKey *byte) (outputData []byte, combinedCheck uint16, check0 uint16, check1 uint16, check2 uint16) {
return _generalCrypt(data, key, 1, overrideByteKey)
}
// _generalCrypt is a generalized MHF crypto function that can perform both encryption and decryption,
// these two crypto operations are combined into a single function because they shared most of their logic.
func Crypto(data []byte, rotKey uint32, encrypt bool, overrideByteKey *byte) ([]byte, uint16, uint16, uint16, uint16) {
// encrypt: cryptType==0
// decrypt: cryptType==1
func _generalCrypt(data []byte, rotKey uint32, cryptType int, overrideByteKey *byte) ([]byte, uint16, uint16, uint16, uint16) {
cryptKeyTruncByte := byte(((rotKey >> 1) % 999983) & 0xFF)
if overrideByteKey != nil {
cryptKeyTruncByte = *overrideByteKey
}
derivedCryptKey := (uint32(len(data)) * (uint32(cryptKeyTruncByte) + 1)) & 0xFFFFFFFF
derivedCryptKey := int32((uint32(len(data)) * (uint32(cryptKeyTruncByte) + 1)) & 0xFFFFFFFF)
sharedBufIdx := byte(1)
var accumulator0, accumulator1, accumulator2 uint32
accumulator0 := uint32(0)
accumulator1 := uint32(0)
accumulator2 := uint32(0)
var outputData []byte
if encrypt {
if cryptType == 0 {
for i := 0; i < len(data); i++ {
// Do the encryption for this iteration
encKeyIdx := ((derivedCryptKey >> 10) ^ uint32(data[i])) & 0xFF
derivedCryptKey = 1277*derivedCryptKey + 1277
encKeyIdx := int32(((uint32(derivedCryptKey) >> 10) ^ uint32(data[i])) & 0xFF)
derivedCryptKey = (0x4FD * (derivedCryptKey + 1))
encKeyByte := _encryptKey[encKeyIdx]
// Update the checksum accumulators.
accumulator2 = accumulator2 + (uint32(sharedBufIdx) * uint32(data[i]))
accumulator1 = accumulator1 + encKeyIdx
accumulator0 = accumulator0 + uint32(encKeyByte)<<(i&7)
accumulator2 = uint32((accumulator2 + (uint32(sharedBufIdx) * uint32(data[i]))) & 0xFFFFFFFF)
accumulator1 = uint32((accumulator1 + uint32(encKeyIdx)) & 0xFFFFFFFF)
accumulator0 = uint32((accumulator0 + (uint32(encKeyByte)<<(i&7))&0xFFFFFFFF) & 0xFFFFFFFF)
// Append the output.
outputData = append(outputData, _sharedCryptKey[sharedBufIdx]^encKeyByte)
@@ -37,32 +53,32 @@ func Crypto(data []byte, rotKey uint32, encrypt bool, overrideByteKey *byte) ([]
// Update the sharedBufIdx for the next iteration.
sharedBufIdx = data[i]
}
} else {
} else if cryptType == 1 {
for i := 0; i < len(data); i++ {
// Do the decryption for this iteration
oldSharedBufIdx := sharedBufIdx
tIdx := data[i] ^ _sharedCryptKey[sharedBufIdx]
decKeyByte := _decryptKey[tIdx]
sharedBufIdx = byte((derivedCryptKey >> 10) ^ uint32(decKeyByte))
sharedBufIdx = byte(((uint32(derivedCryptKey) >> 10) ^ uint32(decKeyByte)) & 0xFF)
// Update the checksum accumulators.
accumulator0 = accumulator0 + uint32(tIdx)<<(i&7)
accumulator1 = accumulator1 + uint32(decKeyByte)
accumulator2 = accumulator2 + uint32(oldSharedBufIdx)*uint32(sharedBufIdx)
accumulator0 = (accumulator0 + ((uint32(tIdx) << (i & 7)) & 0xFFFFFFFF))
accumulator1 = (accumulator1 + uint32(decKeyByte)) & 0xFFFFFFFF
accumulator2 = (accumulator2 + ((uint32(oldSharedBufIdx) * uint32(sharedBufIdx)) & 0xFFFFFFFF)) & 0xFFFFFFFF
// Append the output.
outputData = append(outputData, sharedBufIdx)
// Update the key pos for next iteration.
derivedCryptKey = 1277*derivedCryptKey + 1277
derivedCryptKey = (0x4FD * (derivedCryptKey + 1))
}
}
var check [4]uint16
check[0] = uint16(accumulator1 + (accumulator0 >> 1) + (accumulator2 >> 2))
check[1] = uint16(accumulator0 ^ ((accumulator0 & 0xFFFF0000) >> 16))
check[2] = uint16(accumulator1 ^ ((accumulator1 & 0xFFFF0000) >> 16))
check[3] = uint16(accumulator2 ^ ((accumulator2 & 0xFFFF0000) >> 16))
combinedCheck := uint16((accumulator1 + (accumulator0 >> 1) + (accumulator2 >> 2)) & 0xFFFF)
check0 := uint16((accumulator0 ^ ((accumulator0 & 0xFFFF0000) >> 16)) & 0xFFFF)
check1 := uint16((accumulator1 ^ ((accumulator1 & 0xFFFF0000) >> 16)) & 0xFFFF)
check2 := uint16((accumulator2 ^ ((accumulator2 & 0xFFFF0000) >> 16)) & 0xFFFF)
return outputData, check[0], check[1], check[2], check[3]
return outputData, combinedCheck, check0, check1, check2
}

View File

@@ -65,7 +65,7 @@ func TestEncrypt(t *testing.T) {
for k, tt := range tests {
testname := fmt.Sprintf("encrypt_test_%d", k)
t.Run(testname, func(t *testing.T) {
out, cc, c0, c1, c2 := Crypto(tt.decryptedData, tt.key, true, nil)
out, cc, c0, c1, c2 := Encrypt(tt.decryptedData, tt.key, nil)
if cc != tt.ecc {
t.Errorf("got cc 0x%X, want 0x%X", cc, tt.ecc)
} else if c0 != tt.ec0 {
@@ -86,7 +86,7 @@ func TestDecrypt(t *testing.T) {
for k, tt := range tests {
testname := fmt.Sprintf("decrypt_test_%d", k)
t.Run(testname, func(t *testing.T) {
out, cc, c0, c1, c2 := Crypto(tt.decryptedData, tt.key, false, nil)
out, cc, c0, c1, c2 := Decrypt(tt.encryptedData, tt.key, nil)
if cc != tt.ecc {
t.Errorf("got cc 0x%X, want 0x%X", cc, tt.ecc)
} else if c0 != tt.ec0 {

View File

@@ -5,8 +5,8 @@ import (
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
)
// MsgHead represents the MSG_HEAD

View File

@@ -5,8 +5,8 @@ import (
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
)
// MsgMhfAcceptReadReward represents the MSG_MHF_ACCEPT_READ_REWARD

View File

@@ -3,16 +3,16 @@ package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
)
// MsgMhfAcquireDistItem represents the MSG_MHF_ACQUIRE_DIST_ITEM
type MsgMhfAcquireDistItem struct {
AckHandle uint32
AckHandle uint32
DistributionType uint8
DistributionID uint32
DistributionID uint32
}
// Opcode returns the ID associated with this packet type.

View File

@@ -1,9 +1,9 @@
package mhfpacket
import (
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
)
// MsgMhfAcquireExchangeShop represents the MSG_MHF_ACQUIRE_EXCHANGE_SHOP

View File

@@ -13,7 +13,7 @@ type MsgMhfAcquireFesta struct {
AckHandle uint32
FestaID uint32
GuildID uint32
Unk uint8
Unk uint16
}
// Opcode returns the ID associated with this packet type.
@@ -26,8 +26,7 @@ func (m *MsgMhfAcquireFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien
m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
m.Unk = bf.ReadUint8()
bf.ReadUint8() // Zeroed
m.Unk = bf.ReadUint16()
return nil
}

View File

@@ -3,15 +3,15 @@ package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
)
// MsgMhfAcquireFestaIntermediatePrize represents the MSG_MHF_ACQUIRE_FESTA_INTERMEDIATE_PRIZE
type MsgMhfAcquireFestaIntermediatePrize struct {
AckHandle uint32
PrizeID uint32
PrizeID uint32
}
// Opcode returns the ID associated with this packet type.
@@ -22,7 +22,7 @@ func (m *MsgMhfAcquireFestaIntermediatePrize) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAcquireFestaIntermediatePrize) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.PrizeID = bf.ReadUint32()
m.PrizeID = bf.ReadUint32()
return nil
}

View File

@@ -1,17 +1,17 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAcquireFestaPersonalPrize represents the MSG_MHF_ACQUIRE_FESTA_PERSONAL_PRIZE
type MsgMhfAcquireFestaPersonalPrize struct {
AckHandle uint32
PrizeID uint32
AckHandle uint32
PrizeID uint32
}
// Opcode returns the ID associated with this packet type.
@@ -21,9 +21,9 @@ func (m *MsgMhfAcquireFestaPersonalPrize) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAcquireFestaPersonalPrize) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.PrizeID = bf.ReadUint32()
return nil
m.AckHandle = bf.ReadUint32()
m.PrizeID = bf.ReadUint32()
return nil
}
// Build builds a binary packet from the current data.

View File

@@ -1,17 +1,17 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAcquireGuildAdventure represents the MSG_MHF_ACQUIRE_GUILD_ADVENTURE
type MsgMhfAcquireGuildAdventure struct {
AckHandle uint32
ID uint32
AckHandle uint32
ID uint32
}
// Opcode returns the ID associated with this packet type.
@@ -21,9 +21,9 @@ func (m *MsgMhfAcquireGuildAdventure) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAcquireGuildAdventure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.ID = bf.ReadUint32()
return nil
m.AckHandle = bf.ReadUint32()
m.ID = bf.ReadUint32()
return nil
}
// Build builds a binary packet from the current data.

View File

@@ -12,7 +12,7 @@ import (
type MsgMhfAcquireGuildTresure struct {
AckHandle uint32
HuntID uint32
Unk bool
Unk uint8
}
// Opcode returns the ID associated with this packet type.
@@ -24,7 +24,7 @@ func (m *MsgMhfAcquireGuildTresure) Opcode() network.PacketID {
func (m *MsgMhfAcquireGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.HuntID = bf.ReadUint32()
m.Unk = bf.ReadBool()
m.Unk = bf.ReadUint8()
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAcquireGuildTresureSouvenir represents the MSG_MHF_ACQUIRE_GUILD_TRESURE_SOUVENIR

View File

@@ -11,9 +11,9 @@ import (
// MsgMhfAcquireMonthlyItem represents the MSG_MHF_ACQUIRE_MONTHLY_ITEM
type MsgMhfAcquireMonthlyItem struct {
AckHandle uint32
Unk0 uint8
Unk1 uint8
Unk2 uint16
Unk0 uint16
Unk1 uint16
Unk2 uint32
Unk3 uint32
}
@@ -25,11 +25,10 @@ func (m *MsgMhfAcquireMonthlyItem) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAcquireMonthlyItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint8()
m.Unk2 = bf.ReadUint16()
m.Unk0 = bf.ReadUint16()
m.Unk1 = bf.ReadUint16()
m.Unk2 = bf.ReadUint32()
m.Unk3 = bf.ReadUint32()
bf.ReadUint32() // Zeroed
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAcquireMonthlyReward represents the MSG_MHF_ACQUIRE_MONTHLY_REWARD

View File

@@ -11,7 +11,9 @@ import (
// MsgMhfAcquireTitle represents the MSG_MHF_ACQUIRE_TITLE
type MsgMhfAcquireTitle struct {
AckHandle uint32
TitleIDs []uint16
Unk0 uint16
Unk1 uint16
TitleID uint16
}
// Opcode returns the ID associated with this packet type.
@@ -22,11 +24,9 @@ func (m *MsgMhfAcquireTitle) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAcquireTitle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
titles := int(bf.ReadUint16())
bf.ReadUint16() // Zeroed
for i := 0; i < titles; i++ {
m.TitleIDs = append(m.TitleIDs, bf.ReadUint16())
}
m.Unk0 = bf.ReadUint16()
m.Unk1 = bf.ReadUint16()
m.TitleID = bf.ReadUint16()
return nil
}

View File

@@ -1,30 +1,30 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAcquireUdItem represents the MSG_MHF_ACQUIRE_UD_ITEM
type MsgMhfAcquireUdItem struct {
AckHandle uint32
Unk0 uint8
// from gal
// daily = 0
// personal = 1
// personal rank = 2
// guild rank = 3
// gcp = 4
// from cat
// treasure achievement = 5
// personal achievement = 6
// guild achievement = 7
RewardType uint8
Unk2 uint8 // Number of uint32s to read?
Unk3 []byte
AckHandle uint32
Unk0 uint8
// from gal
// daily = 0
// personal = 1
// personal rank = 2
// guild rank = 3
// gcp = 4
// from cat
// treasure achievement = 5
// personal achievement = 6
// guild achievement = 7
RewardType uint8
Unk2 uint8 // Number of uint32s to read?
Unk3 []byte
}
// Opcode returns the ID associated with this packet type.
@@ -34,13 +34,13 @@ func (m *MsgMhfAcquireUdItem) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAcquireUdItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8()
m.RewardType = bf.ReadUint8()
m.Unk2 = bf.ReadUint8()
for i := uint8(0); i < m.Unk2; i++ {
bf.ReadUint32()
}
m.Unk2 = bf.ReadUint8()
for i := uint8(0); i < m.Unk2; i++ {
bf.ReadUint32()
}
return nil
}

View File

@@ -1,18 +1,18 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAddGuildMissionCount represents the MSG_MHF_ADD_GUILD_MISSION_COUNT
type MsgMhfAddGuildMissionCount struct {
AckHandle uint32
MissionID uint32
Count uint32
AckHandle uint32
MissionID uint32
Count uint32
}
// Opcode returns the ID associated with this packet type.
@@ -22,10 +22,10 @@ func (m *MsgMhfAddGuildMissionCount) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAddGuildMissionCount) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.MissionID = bf.ReadUint32()
m.Count = bf.ReadUint32()
return nil
m.AckHandle = bf.ReadUint32()
m.MissionID = bf.ReadUint32()
m.Count = bf.ReadUint32()
return nil
}
// Build builds a binary packet from the current data.

View File

@@ -1,17 +1,17 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAddGuildWeeklyBonusExceptionalUser represents the MSG_MHF_ADD_GUILD_WEEKLY_BONUS_EXCEPTIONAL_USER
type MsgMhfAddGuildWeeklyBonusExceptionalUser struct {
AckHandle uint32
NumUsers uint8
AckHandle uint32
NumUsers uint8
}
// Opcode returns the ID associated with this packet type.
@@ -21,9 +21,9 @@ func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.NumUsers = bf.ReadUint8()
return nil
m.AckHandle = bf.ReadUint32()
m.NumUsers = bf.ReadUint8()
return nil
}
// Build builds a binary packet from the current data.

View File

@@ -1,9 +1,9 @@
package mhfpacket
import (
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
)
// MsgMhfAddKouryouPoint represents the MSG_MHF_ADD_KOURYOU_POINT

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAddRewardSongCount represents the MSG_MHF_ADD_REWARD_SONG_COUNT

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAddUdPoint represents the MSG_MHF_ADD_UD_POINT

View File

@@ -1,9 +1,9 @@
package mhfpacket
import (
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
)
// MsgMhfAddUdTacticsPoint represents the MSG_MHF_ADD_UD_TACTICS_POINT

View File

@@ -14,7 +14,7 @@ type MsgMhfAnnounce struct {
IPAddress uint32
Port uint16
StageID []byte
Data *byteframe.ByteFrame
Type uint8
}
// Opcode returns the ID associated with this packet type.
@@ -31,7 +31,8 @@ func (m *MsgMhfAnnounce) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon
_ = bf.ReadUint8()
_ = bf.ReadUint8()
m.StageID = bf.ReadBytes(32)
m.Data = byteframe.NewByteFrameFromBytes(bf.ReadBytes(uint(bf.ReadUint32())))
_ = bf.ReadUint32()
m.Type = bf.ReadUint8()
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfAnswerGuildScout represents the MSG_MHF_ANSWER_GUILD_SCOUT

View File

@@ -1,9 +1,7 @@
package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
_config "erupe-ce/config"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
@@ -27,16 +25,17 @@ func (m *MsgMhfApplyDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clie
m.AckHandle = bf.ReadUint32()
m.DistributionType = bf.ReadUint8()
m.DistributionID = bf.ReadUint32()
if _config.ErupeConfig.RealClientMode >= _config.G8 {
m.Unk2 = bf.ReadUint32()
}
if _config.ErupeConfig.RealClientMode >= _config.G10 {
m.Unk3 = bf.ReadUint32()
}
m.Unk2 = bf.ReadUint32()
m.Unk3 = bf.ReadUint32()
return nil
}
// Build builds a binary packet from the current data.
func (m *MsgMhfApplyDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.AckHandle)
bf.WriteUint8(m.DistributionType)
bf.WriteUint32(m.DistributionID)
bf.WriteUint32(m.Unk2)
bf.WriteUint32(m.Unk3)
return nil
}

View File

@@ -1,7 +1,6 @@
package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
@@ -23,11 +22,11 @@ func (m *MsgMhfArrangeGuildMember) Opcode() network.PacketID {
func (m *MsgMhfArrangeGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
bf.ReadUint8() // Zeroed
charCount := int(bf.ReadUint8())
charCount := bf.ReadUint16()
m.CharIDs = make([]uint32, charCount)
for i := 0; i < charCount; i++ {
for i := uint16(0); i < charCount; i++ {
m.CharIDs[i] = bf.ReadUint32()
}
@@ -36,5 +35,13 @@ func (m *MsgMhfArrangeGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx
// Build builds a binary packet from the current data.
func (m *MsgMhfArrangeGuildMember) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.AckHandle)
bf.WriteUint32(m.GuildID)
bf.WriteUint16(uint16(len(m.CharIDs)))
for _, charID := range m.CharIDs {
bf.WriteUint32(charID)
}
return nil
}

View File

@@ -1,17 +1,17 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfCancelGuildMissionTarget represents the MSG_MHF_CANCEL_GUILD_MISSION_TARGET
type MsgMhfCancelGuildMissionTarget struct {
AckHandle uint32
MissionID uint32
AckHandle uint32
MissionID uint32
}
// Opcode returns the ID associated with this packet type.
@@ -21,9 +21,9 @@ func (m *MsgMhfCancelGuildMissionTarget) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfCancelGuildMissionTarget) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.MissionID = bf.ReadUint32()
return nil
m.AckHandle = bf.ReadUint32()
m.MissionID = bf.ReadUint32()
return nil
}
// Build builds a binary packet from the current data.

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfCancelGuildScout represents the MSG_MHF_CANCEL_GUILD_SCOUT

View File

@@ -13,8 +13,7 @@ type MsgMhfChargeFesta struct {
AckHandle uint32
FestaID uint32
GuildID uint32
Souls []uint16
Auto bool
Souls int
}
// Opcode returns the ID associated with this packet type.
@@ -27,10 +26,11 @@ func (m *MsgMhfChargeFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Client
m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
m.Souls = 0
for i := bf.ReadUint16(); i > 0; i-- {
m.Souls = append(m.Souls, bf.ReadUint16())
m.Souls += int(bf.ReadUint16())
}
m.Auto = bf.ReadBool()
_ = bf.ReadUint8() // Unk
return nil
}

View File

@@ -1,18 +1,18 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfChargeGuildAdventure represents the MSG_MHF_CHARGE_GUILD_ADVENTURE
type MsgMhfChargeGuildAdventure struct {
AckHandle uint32
ID uint32
Amount uint32
AckHandle uint32
ID uint32
Amount uint32
}
// Opcode returns the ID associated with this packet type.
@@ -22,10 +22,10 @@ func (m *MsgMhfChargeGuildAdventure) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfChargeGuildAdventure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.ID = bf.ReadUint32()
m.Amount = bf.ReadUint32()
return nil
m.AckHandle = bf.ReadUint32()
m.ID = bf.ReadUint32()
m.Amount = bf.ReadUint32()
return nil
}
// Build builds a binary packet from the current data.

View File

@@ -1,7 +1,6 @@
package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
@@ -26,5 +25,7 @@ func (m *MsgMhfCheckDailyCafepoint) Parse(bf *byteframe.ByteFrame, ctx *clientct
}
func (m *MsgMhfCheckDailyCafepoint) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.AckHandle)
bf.WriteUint32(m.Unk)
return nil
}

View File

@@ -12,6 +12,7 @@ import (
type MsgMhfCheckMonthlyItem struct {
AckHandle uint32
Type uint8
Unk []byte
}
// Opcode returns the ID associated with this packet type.
@@ -23,9 +24,7 @@ func (m *MsgMhfCheckMonthlyItem) Opcode() network.PacketID {
func (m *MsgMhfCheckMonthlyItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.Type = bf.ReadUint8()
bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
m.Unk = bf.ReadBytes(3)
return nil
}

View File

@@ -12,6 +12,7 @@ type MsgMhfCheckWeeklyStamp struct {
AckHandle uint32
StampType string
Unk1 bool
Unk2 uint16 // Hardcoded 0 in the binary
}
// Opcode returns the ID associated with this packet type.
@@ -30,7 +31,7 @@ func (m *MsgMhfCheckWeeklyStamp) Parse(bf *byteframe.ByteFrame, ctx *clientctx.C
m.StampType = "ex"
}
m.Unk1 = bf.ReadBool()
bf.ReadUint16() // Zeroed
m.Unk2 = bf.ReadUint16()
return nil
}

View File

@@ -12,6 +12,8 @@ import (
// MsgMhfCreateGuild represents the MSG_MHF_CREATE_GUILD
type MsgMhfCreateGuild struct {
AckHandle uint32
Unk0 uint8
Unk1 uint8
Name string
}
@@ -23,8 +25,9 @@ func (m *MsgMhfCreateGuild) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfCreateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
bf.ReadUint16() // Zeroed
bf.ReadUint16() // Name length
m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint8()
_ = bf.ReadUint16() // len
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil
}

View File

@@ -25,8 +25,7 @@ func (m *MsgMhfCreateJoint) Opcode() network.PacketID {
func (m *MsgMhfCreateJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
bf.ReadUint16() // Zeroed
bf.ReadUint16() // Name length
_ = bf.ReadUint32() // len
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfCreateMercenary represents the MSG_MHF_CREATE_MERCENARY

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfDebugPostValue represents the MSG_MHF_DEBUG_POST_VALUE

View File

@@ -1,14 +1,15 @@
package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfDisplayedAchievement represents the MSG_MHF_DISPLAYED_ACHIEVEMENT
type MsgMhfDisplayedAchievement struct{}
type MsgMhfDisplayedAchievement struct {
Unk0 uint8
}
// Opcode returns the ID associated with this packet type.
func (m *MsgMhfDisplayedAchievement) Opcode() network.PacketID {
@@ -17,11 +18,12 @@ func (m *MsgMhfDisplayedAchievement) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfDisplayedAchievement) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.ReadUint8() // Zeroed
m.Unk0 = bf.ReadUint8()
return nil
}
// Build builds a binary packet from the current data.
func (m *MsgMhfDisplayedAchievement) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
bf.WriteUint8(m.Unk0)
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfEnterTournamentQuest represents the MSG_MHF_ENTER_TOURNAMENT_QUEST

View File

@@ -25,7 +25,7 @@ func (m *MsgMhfEntryFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientC
m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
bf.ReadUint16() // Zeroed
_ = bf.ReadUint16() // Always 0
return nil
}

View File

@@ -1,9 +1,7 @@
package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
_config "erupe-ce/config"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
@@ -11,10 +9,9 @@ import (
// MsgMhfEnumerateDistItem represents the MSG_MHF_ENUMERATE_DIST_ITEM
type MsgMhfEnumerateDistItem struct {
AckHandle uint32
DistType uint8
Unk1 uint8
Unk0 uint8
Unk1 uint16
Unk2 uint16
Unk3 []byte
}
// Opcode returns the ID associated with this packet type.
@@ -25,16 +22,17 @@ func (m *MsgMhfEnumerateDistItem) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfEnumerateDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.DistType = bf.ReadUint8()
m.Unk1 = bf.ReadUint8()
m.Unk2 = bf.ReadUint16() // Maximum? Hardcoded to 256
if _config.ErupeConfig.RealClientMode >= _config.Z1 {
m.Unk3 = bf.ReadBytes(uint(bf.ReadUint8()))
}
m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint16()
m.Unk2 = bf.ReadUint16()
return nil
}
// Build builds a binary packet from the current data.
func (m *MsgMhfEnumerateDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.AckHandle)
bf.WriteUint8(m.Unk0)
bf.WriteUint16(m.Unk1)
bf.WriteUint16(m.Unk2)
return nil
}

View File

@@ -1,7 +1,6 @@
package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
@@ -10,6 +9,8 @@ import (
// MsgMhfEnumerateEvent represents the MSG_MHF_ENUMERATE_EVENT
type MsgMhfEnumerateEvent struct {
AckHandle uint32
Unk0 uint16 // Hardcoded 0 in the binary
Unk1 uint16 // Hardcoded 0 in the binary
}
// Opcode returns the ID associated with this packet type.
@@ -20,12 +21,15 @@ func (m *MsgMhfEnumerateEvent) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfEnumerateEvent) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
bf.ReadUint16() // Zeroed
bf.ReadUint16() // Zeroed
m.Unk0 = bf.ReadUint16()
m.Unk1 = bf.ReadUint16()
return nil
}
// Build builds a binary packet from the current data.
func (m *MsgMhfEnumerateEvent) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.AckHandle)
bf.WriteUint16(m.Unk0)
bf.WriteUint16(m.Unk1)
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfEnumerateFestaIntermediatePrize represents the MSG_MHF_ENUMERATE_FESTA_INTERMEDIATE_PRIZE

View File

@@ -25,7 +25,7 @@ func (m *MsgMhfEnumerateFestaMember) Parse(bf *byteframe.ByteFrame, ctx *clientc
m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
bf.ReadUint16() // Zeroed
_ = bf.ReadUint16() // Hardcoded 0 in the binary.
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfEnumerateFestaPersonalPrize represents the MSG_MHF_ENUMERATE_FESTA_PERSONAL_PRIZE

View File

@@ -10,7 +10,8 @@ import (
// MsgMhfEnumerateGuacot represents the MSG_MHF_ENUMERATE_GUACOT
type MsgMhfEnumerateGuacot struct {
AckHandle uint32
Unk0 uint32
Unk0 uint32 // Hardcoded 0 in binary
Unk1 uint16 // Hardcoded 0 in binary
}
// Opcode returns the ID associated with this packet type.
@@ -22,7 +23,7 @@ func (m *MsgMhfEnumerateGuacot) Opcode() network.PacketID {
func (m *MsgMhfEnumerateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32()
bf.ReadUint16() // Zeroed
m.Unk1 = bf.ReadUint16()
return nil
}

View File

@@ -2,7 +2,9 @@ package mhfpacket
import (
"errors"
"erupe-ce/common/bfutil"
"erupe-ce/common/byteframe"
"erupe-ce/common/stringsupport"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
@@ -32,8 +34,8 @@ type MsgMhfEnumerateGuild struct {
Type EnumerateGuildType
Page uint8
Sorting bool
Data1 *byteframe.ByteFrame
Data2 *byteframe.ByteFrame
Data1 []byte
Data2 string
}
// Opcode returns the ID associated with this packet type.
@@ -47,12 +49,12 @@ func (m *MsgMhfEnumerateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
m.Type = EnumerateGuildType(bf.ReadUint8())
m.Page = bf.ReadUint8()
m.Sorting = bf.ReadBool()
bf.ReadUint8() // Zeroed
m.Data1 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(4))
bf.ReadUint16() // Zeroed
dataLen := uint(bf.ReadUint8())
bf.ReadUint8() // Zeroed
m.Data2 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(dataLen))
_ = bf.ReadBytes(1)
m.Data1 = bf.ReadBytes(4)
_ = bf.ReadBytes(2)
lenData2 := uint(bf.ReadUint8())
_ = bf.ReadBytes(1)
m.Data2 = stringsupport.SJISToUTF8(bfutil.UpToNull(bf.ReadBytes(lenData2)))
return nil
}

View File

@@ -11,7 +11,8 @@ import (
// MsgMhfEnumerateGuildItem represents the MSG_MHF_ENUMERATE_GUILD_ITEM
type MsgMhfEnumerateGuildItem struct {
AckHandle uint32
GuildID uint32
GuildId uint32
Unk0 uint16
}
// Opcode returns the ID associated with this packet type.
@@ -22,9 +23,8 @@ func (m *MsgMhfEnumerateGuildItem) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfEnumerateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
m.GuildId = bf.ReadUint32()
m.Unk0 = bf.ReadUint16()
return nil
}

View File

@@ -1,7 +1,6 @@
package mhfpacket
import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
@@ -9,9 +8,10 @@ import (
// MsgMhfEnumerateGuildMember represents the MSG_MHF_ENUMERATE_GUILD_MEMBER
type MsgMhfEnumerateGuildMember struct {
AckHandle uint32
AllianceID uint32
GuildID uint32
AckHandle uint32
Unk0 uint16 // Hardcoded 00 01 in the binary
Unk1 uint32 // Alliance related
GuildID uint32
}
// Opcode returns the ID associated with this packet type.
@@ -22,14 +22,17 @@ func (m *MsgMhfEnumerateGuildMember) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfEnumerateGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
bf.ReadUint8() // Zeroed
bf.ReadUint8() // Always 1
m.AllianceID = bf.ReadUint32()
m.Unk0 = bf.ReadUint16()
m.Unk1 = bf.ReadUint32()
m.GuildID = bf.ReadUint32()
return nil
}
// Build builds a binary packet from the current data.
func (m *MsgMhfEnumerateGuildMember) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.AckHandle)
bf.WriteUint16(m.Unk0)
bf.WriteUint32(m.Unk1)
bf.WriteUint32(m.GuildID)
return nil
}

View File

@@ -12,8 +12,7 @@ import (
type MsgMhfEnumerateGuildTresure struct {
AckHandle uint32
MaxHunts uint16
Unk0 uint16
Unk1 uint16
Unk uint32
}
// Opcode returns the ID associated with this packet type.
@@ -25,8 +24,9 @@ func (m *MsgMhfEnumerateGuildTresure) Opcode() network.PacketID {
func (m *MsgMhfEnumerateGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.MaxHunts = bf.ReadUint16()
m.Unk0 = bf.ReadUint16()
m.Unk1 = bf.ReadUint16()
// Changes with MaxHunts
// 0 if MaxHunts = 1, 1 if MaxHunts = 30
m.Unk = bf.ReadUint32()
return nil
}

View File

@@ -14,6 +14,7 @@ type MsgMhfEnumerateHouse struct {
AckHandle uint32
CharID uint32
Method uint8
Unk uint16
Name string
}
@@ -27,7 +28,7 @@ func (m *MsgMhfEnumerateHouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
m.AckHandle = bf.ReadUint32()
m.CharID = bf.ReadUint32()
m.Method = bf.ReadUint8()
bf.ReadUint16() // Zeroed
m.Unk = bf.ReadUint16()
lenName := bf.ReadUint8()
if lenName > 0 {
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())

View File

@@ -10,13 +10,8 @@ import (
// MsgMhfEnumerateInvGuild represents the MSG_MHF_ENUMERATE_INV_GUILD
type MsgMhfEnumerateInvGuild struct {
AckHandle uint32
Unk uint32
Operation uint8
ActiveHours uint8
DaysActive uint8
PlayStyle uint8
GuildRequest uint8
AckHandle uint32
Unk []byte
}
// Opcode returns the ID associated with this packet type.
@@ -27,12 +22,7 @@ func (m *MsgMhfEnumerateInvGuild) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgMhfEnumerateInvGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32()
m.Unk = bf.ReadUint32()
m.Operation = bf.ReadUint8()
m.ActiveHours = bf.ReadUint8()
m.DaysActive = bf.ReadUint8()
m.PlayStyle = bf.ReadUint8()
m.GuildRequest = bf.ReadUint8()
m.Unk = bf.ReadBytes(9)
return nil
}

View File

@@ -1,11 +1,11 @@
package mhfpacket
import (
"errors"
"errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
)
// MsgMhfEnumerateMercenaryLog represents the MSG_MHF_ENUMERATE_MERCENARY_LOG

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