Hi
This commit is contained in:
parent
2e25d47cd4
commit
b62a013017
32 changed files with 226061 additions and 1 deletions
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
# ---> OCaml
|
||||
*.annot
|
||||
*.cmo
|
||||
*.cma
|
||||
*.cmi
|
||||
*.a
|
||||
*.o
|
||||
*.cmx
|
||||
*.cmxs
|
||||
*.cmxa
|
||||
|
||||
# ocamlbuild working directory
|
||||
_build/
|
||||
|
||||
# ocamlbuild targets
|
||||
*.byte
|
||||
*.native
|
||||
|
||||
# oasis generated files
|
||||
setup.data
|
||||
setup.log
|
||||
|
||||
# Merlin configuring file for Vim and Emacs
|
||||
.merlin
|
||||
|
||||
# Dune generated files
|
||||
*.install
|
||||
|
||||
# Local OPAM switch
|
||||
_opam/
|
||||
|
||||
# Protocol definition files
|
||||
/sdkserver/protocol.proto
|
||||
/gameserver/protocol.proto
|
50
README.md
50
README.md
|
@ -1,3 +1,51 @@
|
|||
# LingshaSR
|
||||
#### An experimental Honkai: Star Rail 2.4.51 server emulator
|
||||
|
||||
Honkai: Star Rail 2.4.51 server emulator
|
||||
![screenshot](https://git.xeondev.com/reversedrooms/LingshaSR/raw/branch/master/screenshot.png)
|
||||
|
||||
## Requirements
|
||||
[OCaml](https://opam.ocaml.org/blog/opam-2-2-0/)
|
||||
|
||||
## Running
|
||||
### From source
|
||||
|
||||
```
|
||||
git clone https://git.xeondev.com/reversedrooms/LingshaSR.git
|
||||
cd LingshaSR
|
||||
|
||||
cd sdkserver
|
||||
opam install . --deps-only
|
||||
opam exec -- dune exec sdkserver
|
||||
|
||||
cd gameserver
|
||||
opam install . --deps-only
|
||||
opam exec -- dune exec gameserver
|
||||
```
|
||||
|
||||
|
||||
### Using Pre-built Binaries
|
||||
Navigate to the [Releases](https://git.xeondev.com/reversedrooms/LingshaSR/releases)
|
||||
page and download the latest release for your platform.
|
||||
|
||||
## Connecting
|
||||
[Get 2.5 beta client](https://git.xeondev.com/xeon/3/raw/branch/3/HSR2.5_beta_reversedrooms.torrent),
|
||||
replace [mhypbase.dll](https://git.xeondev.com/reversedrooms/LingshaSR/raw/branch/master/mhypbase.dll)
|
||||
file in your game folder, it will redirect game traffic (and disable in-game censorship)
|
||||
|
||||
## Functionality (work in progress)
|
||||
- Login and player spawn
|
||||
- Battle via calyx
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests are welcome. For major changes, please open an issue first to discuss
|
||||
what you would like to change, and why.
|
||||
|
||||
## Bug Reports
|
||||
|
||||
If you find a bug, please open an issue with as much detail as possible. If you
|
||||
can, please include steps to reproduce the bug.
|
||||
|
||||
Bad issues such as "This doesn't work" will be closed immediately, be _sure_ to
|
||||
provide exact detailed steps to reproduce your bug. If it's hard to reproduce, try
|
||||
to explain it and write a reproducer as best as you can.
|
1576
gameserver/bin/cmdid.ml
Normal file
1576
gameserver/bin/cmdid.ml
Normal file
File diff suppressed because it is too large
Load diff
41
gameserver/bin/connection.ml
Normal file
41
gameserver/bin/connection.ml
Normal file
|
@ -0,0 +1,41 @@
|
|||
open Lwt
|
||||
open Lwt.Syntax
|
||||
open Printf
|
||||
open Packet
|
||||
|
||||
module CmdMap = Map.Make(Int)
|
||||
let handlers = let open Handlers in let open Cmdid in CmdMap.(empty
|
||||
|> add cmd_player_get_token_cs_req Login.on_player_get_token
|
||||
|> add cmd_player_login_cs_req Login.on_player_login
|
||||
|> add cmd_player_login_finish_cs_req Login.on_player_login_finish
|
||||
|> add cmd_player_heart_beat_cs_req Player.on_player_heartbeat
|
||||
|> add cmd_get_basic_info_cs_req Player.on_get_basic_info
|
||||
|> add cmd_get_avatar_data_cs_req Avatar.on_get_avatar_data
|
||||
|> add cmd_get_bag_cs_req Item.on_get_bag
|
||||
|> add cmd_get_multi_path_avatar_info_cs_req Avatar.on_get_multi_path_avatar_info
|
||||
|> add cmd_get_mission_status_cs_req Mission.on_get_mission_status
|
||||
|> add cmd_get_cur_lineup_data_cs_req Lineup.on_get_cur_lineup_data
|
||||
|> add cmd_get_cur_scene_info_cs_req Scene.on_get_cur_scene_info
|
||||
|> add cmd_start_cocoon_stage_cs_req Battle.on_start_cocoon_stage
|
||||
|> add cmd_p_v_e_battle_result_cs_req Battle.on_pve_battle_result
|
||||
)
|
||||
|
||||
let handle pk =
|
||||
match CmdMap.find_opt pk.cmd handlers with
|
||||
| Some handler -> Some (handler pk)
|
||||
| None -> printf "unhandled cmd: %d\n%!" pk.cmd; None
|
||||
|
||||
let rec run ic oc =
|
||||
let* pk = read ic in
|
||||
|
||||
let head = Hex.show (Hex.of_string pk.head) in
|
||||
let body = Hex.show (Hex.of_string pk.body) in
|
||||
|
||||
printf "packet cmd: %d, head: %s, body: %s\n%!" pk.cmd head body;
|
||||
|
||||
let* () = match handle pk with
|
||||
| Some pk -> write oc pk
|
||||
| None -> return_unit
|
||||
in
|
||||
|
||||
run ic oc
|
5
gameserver/bin/dune
Normal file
5
gameserver/bin/dune
Normal file
|
@ -0,0 +1,5 @@
|
|||
(executable
|
||||
(public_name gameserver)
|
||||
(name main)
|
||||
(libraries lwt.unix hex base64 pbrt gameserver))
|
||||
(include_subdirs qualified)
|
35
gameserver/bin/gateway.ml
Normal file
35
gameserver/bin/gateway.ml
Normal file
|
@ -0,0 +1,35 @@
|
|||
open Lwt
|
||||
open Lwt.Syntax
|
||||
open Printf
|
||||
|
||||
let bind_sock addr port =
|
||||
let open Lwt_unix in
|
||||
|
||||
let listener = socket PF_INET SOCK_STREAM 0 in
|
||||
setsockopt listener SO_REUSEADDR true;
|
||||
|
||||
let* () = bind listener @@ ADDR_INET(Unix.inet_addr_of_string addr, port) in
|
||||
listen listener 100;
|
||||
return listener
|
||||
|
||||
let accept_connection (sock, addr) =
|
||||
let (remote_ip, remote_port) = match addr with
|
||||
| Unix.ADDR_INET (addr, port) -> Unix.string_of_inet_addr addr, port
|
||||
| _ -> failwith "only ADDR_INET is supported"
|
||||
in
|
||||
|
||||
let ic = Lwt_io.of_fd ~mode:Lwt_io.Input sock in
|
||||
let oc = Lwt_io.of_fd ~mode:Lwt_io.Output sock in
|
||||
on_failure (Connection.run ic oc) (fun err -> printf "error: %s\n%!" (Printexc.to_string err));
|
||||
|
||||
printf "new connection from %s:%d\n%!" remote_ip remote_port; return_unit
|
||||
|
||||
let accept_loop listener =
|
||||
let rec accept () =
|
||||
Lwt_unix.accept listener >>= accept_connection >>= accept
|
||||
in accept
|
||||
|
||||
let listen addr port =
|
||||
Lwt_main.run ((bind_sock addr port) >>= fun listener ->
|
||||
printf "gateway is listening at %s:%d\n%!" addr port;
|
||||
let accept = accept_loop listener in accept ())
|
23
gameserver/bin/handlers/avatar.ml
Normal file
23
gameserver/bin/handlers/avatar.ml
Normal file
|
@ -0,0 +1,23 @@
|
|||
open Cmdid
|
||||
open Protocol
|
||||
open Packet
|
||||
|
||||
let on_get_avatar_data pk =
|
||||
let dec = Pbrt.Decoder.of_string pk.body in
|
||||
let req = decode_pb_get_avatar_data_cs_req dec in
|
||||
|
||||
let rsp = default_get_avatar_data_sc_rsp
|
||||
~is_all:req.is_get_all
|
||||
~avatar_list:[
|
||||
default_avatar
|
||||
~base_avatar_id:1222l
|
||||
~level:80l
|
||||
~promotion:6l
|
||||
~rank:6l
|
||||
()
|
||||
]
|
||||
() in
|
||||
|
||||
pack cmd_get_avatar_data_sc_rsp encode_pb_get_avatar_data_sc_rsp rsp
|
||||
|
||||
let on_get_multi_path_avatar_info _pk = empty cmd_get_multi_path_avatar_info_sc_rsp
|
48
gameserver/bin/handlers/battle.ml
Normal file
48
gameserver/bin/handlers/battle.ml
Normal file
|
@ -0,0 +1,48 @@
|
|||
open Cmdid
|
||||
open Protocol
|
||||
open Packet
|
||||
|
||||
let on_start_cocoon_stage pk =
|
||||
let dec = Pbrt.Decoder.of_string pk.body in
|
||||
let req = decode_pb_start_cocoon_stage_cs_req dec in
|
||||
|
||||
let avatar = default_battle_avatar
|
||||
~id:1222l
|
||||
~hp:10000l
|
||||
~level:80l
|
||||
~rank:6l
|
||||
~promotion:6l
|
||||
~avatar_type:Avatar_formal_type
|
||||
~sp:(Some {sp_cur = 10000l; sp_need = 10000l})
|
||||
() in
|
||||
|
||||
let wave = default_scene_monster_wave
|
||||
~monster_list: [default_scene_monster_info ~monster_id:3024020l ()] () in
|
||||
|
||||
let battle = default_scene_battle_info
|
||||
~battle_id:1l
|
||||
~stage_id:201012311l
|
||||
~logic_random_seed: (Int32.of_float (Unix.gettimeofday ()))
|
||||
~monster_wave_list:[wave]
|
||||
~battle_avatar_list:[avatar]
|
||||
() in
|
||||
|
||||
let rsp = default_start_cocoon_stage_sc_rsp
|
||||
~battle_info:(Some battle)
|
||||
~cocoon_id:req.cocoon_id
|
||||
~prop_entity_id:req.prop_entity_id
|
||||
~wave:1l
|
||||
() in
|
||||
|
||||
pack cmd_start_cocoon_stage_sc_rsp encode_pb_start_cocoon_stage_sc_rsp rsp
|
||||
|
||||
let on_pve_battle_result pk =
|
||||
let dec = Pbrt.Decoder.of_string pk.body in
|
||||
let req = decode_pb_pve_battle_result_cs_req dec in
|
||||
|
||||
let rsp = default_pve_battle_result_sc_rsp
|
||||
~end_status:req.end_status
|
||||
~battle_id:req.battle_id
|
||||
() in
|
||||
|
||||
pack cmd_p_v_e_battle_result_sc_rsp encode_pb_pve_battle_result_sc_rsp rsp
|
4
gameserver/bin/handlers/item.ml
Normal file
4
gameserver/bin/handlers/item.ml
Normal file
|
@ -0,0 +1,4 @@
|
|||
open Cmdid
|
||||
open Packet
|
||||
|
||||
let on_get_bag _pk = empty cmd_get_bag_sc_rsp
|
23
gameserver/bin/handlers/lineup.ml
Normal file
23
gameserver/bin/handlers/lineup.ml
Normal file
|
@ -0,0 +1,23 @@
|
|||
open Cmdid
|
||||
open Protocol
|
||||
open Packet
|
||||
|
||||
let on_get_cur_lineup_data _pk =
|
||||
let rsp = {
|
||||
retcode = 0l;
|
||||
lineup = Some (default_lineup_info
|
||||
~name:"Lineup"
|
||||
~avatar_list:[
|
||||
{
|
||||
id = 1222l;
|
||||
hp = 10000l;
|
||||
slot = 0l;
|
||||
satiety = 0l;
|
||||
avatar_type = Avatar_formal_type;
|
||||
sp = Some {sp_cur = 10000l; sp_need = 10000l;};
|
||||
}
|
||||
]
|
||||
());
|
||||
} in
|
||||
|
||||
pack cmd_get_cur_lineup_data_sc_rsp encode_pb_get_cur_lineup_data_sc_rsp rsp
|
27
gameserver/bin/handlers/login.ml
Normal file
27
gameserver/bin/handlers/login.ml
Normal file
|
@ -0,0 +1,27 @@
|
|||
open Cmdid
|
||||
open Protocol
|
||||
open Packet
|
||||
|
||||
let on_player_get_token _pk = pack
|
||||
cmd_player_get_token_sc_rsp
|
||||
encode_pb_player_get_token_sc_rsp
|
||||
(default_player_get_token_sc_rsp ~uid:1337l ())
|
||||
|
||||
let on_player_login _pk = pack
|
||||
cmd_player_login_sc_rsp
|
||||
encode_pb_player_login_sc_rsp
|
||||
(default_player_login_sc_rsp
|
||||
~stamina:240l
|
||||
~basic_info: (Some {
|
||||
nickname = "xeondev";
|
||||
level = 5l;
|
||||
exp = 0l;
|
||||
stamina = 240l;
|
||||
mcoin = 0l;
|
||||
hcoin = 0l;
|
||||
scoin = 0l;
|
||||
world_level = 0l;
|
||||
})
|
||||
())
|
||||
|
||||
let on_player_login_finish _pk = empty cmd_player_login_finish_sc_rsp
|
90
gameserver/bin/handlers/mission.ml
Normal file
90
gameserver/bin/handlers/mission.ml
Normal file
|
@ -0,0 +1,90 @@
|
|||
open Cmdid
|
||||
open Protocol
|
||||
open Packet
|
||||
|
||||
let finished_main_missions = [
|
||||
1000101l; 1000111l; 1000112l; 1000113l; 1000114l; 1000201l; 1000202l; 1000203l; 1000204l; 1000300l;
|
||||
1000301l; 1000302l; 1000303l; 1000304l; 1000400l; 1000401l; 1000402l; 1000410l; 1000500l; 1000501l;
|
||||
1000502l; 1000503l; 1000504l; 1000505l; 1000510l; 1000511l; 1010001l; 1010002l; 1010101l; 1010201l;
|
||||
1010202l; 1010203l; 1010204l; 1010205l; 1010206l; 1010301l; 1010302l; 1010303l; 1010401l; 1010405l;
|
||||
1010402l; 1010403l; 1010500l; 1010501l; 1010502l; 1010503l; 1010601l; 1010602l; 1010700l; 1010701l;
|
||||
1010801l; 1010802l; 1010901l; 1010902l; 1011001l; 1011002l; 1011003l; 1011100l; 1011101l; 1011102l;
|
||||
1011103l; 1011201l; 1011202l; 1011301l; 1011400l; 1011401l; 1011402l; 1011403l; 1011501l; 1011502l;
|
||||
1011503l; 1020101l; 1020201l; 1020302l; 1020301l; 1020400l; 1020401l; 1020402l; 1020403l; 1020501l;
|
||||
1020601l; 1020701l; 1020702l; 1020801l; 1020901l; 1021001l; 1021101l; 1021201l; 1021301l; 1021401l;
|
||||
1021501l; 1021601l; 2000001l; 2000002l; 2000003l; 2000004l; 2000100l; 2000101l; 2000131l; 2000132l;
|
||||
2000133l; 2000110l; 2000111l; 2000301l; 2000103l; 2000112l; 2000108l; 2000104l; 2000102l; 2000105l;
|
||||
2000106l; 2000107l; 2000313l; 2000314l; 2000109l; 2000113l; 2000116l; 2000118l; 2000119l; 2000120l;
|
||||
2000122l; 2000302l; 2000303l; 2000304l; 2000305l; 2000310l; 2000311l; 2000312l; 2000320l; 2000701l;
|
||||
2000702l; 2000703l; 2000704l; 2000705l; 2000706l; 2000707l; 2010005l; 2010301l; 2010302l; 2011103l;
|
||||
2011104l; 2011409l; 2010401l; 2010402l; 2010405l; 2010502l; 2010503l; 2010701l; 2010708l; 2010709l;
|
||||
2010720l; 2010730l; 2010731l; 2010732l; 2010733l; 2010734l; 2010735l; 2010904l; 2011101l; 2011102l;
|
||||
2011105l; 2011301l; 2011302l; 2011303l; 2011501l; 2011502l; 2010909l; 2010910l; 2011901l; 2011902l;
|
||||
2011903l; 2011904l; 2011905l; 2011906l; 2020301l; 2020302l; 2020304l; 2020316l; 2020317l; 2020318l;
|
||||
2020319l; 2020401l; 2020402l; 2020403l; 2020404l; 2020405l; 2020406l; 2020407l; 2020303l; 2020103l;
|
||||
2020104l; 2020105l; 2020106l; 2020107l; 2020108l; 2020109l; 2020110l; 2020201l; 2020202l; 2020203l;
|
||||
2020204l; 2000201l; 2000202l; 2000203l; 2000204l; 2000205l; 2000206l; 2000207l; 2000208l; 2000209l;
|
||||
2000211l; 2000212l; 2010500l; 2010501l; 2010705l; 2010706l; 2010901l; 2010902l; 2010903l; 2010702l;
|
||||
2010703l; 2011400l; 2011401l; 2011406l; 2011402l; 2011403l; 2011404l; 2011405l; 2011407l; 2011408l;
|
||||
2011410l; 2010905l; 2010906l; 2010907l; 2010908l; 2010911l; 2010912l; 2020305l; 2020306l; 2020309l;
|
||||
2020307l; 2020308l; 2020701l; 2020702l; 2020313l; 2020314l; 2020315l; 6020101l; 6020201l; 6020202l;
|
||||
2020801l; 2020802l; 2020901l; 2021601l; 2021602l; 3000201l; 3000202l; 3000203l; 3000211l; 3000212l;
|
||||
3000213l; 3000301l; 3000302l; 3000303l; 3000522l; 3000523l; 3000524l; 3000525l; 3000526l; 3000527l;
|
||||
3000601l; 3000602l; 3000603l; 3000604l; 3000701l; 3000702l; 3000703l; 3000704l; 3000705l; 3000800l;
|
||||
3000801l; 3000802l; 3000803l; 3010102l; 3010103l; 3010104l; 3010105l; 3010201l; 3010202l; 3010203l;
|
||||
3010204l; 3010205l; 3011011l; 3011012l; 3011013l; 3011014l; 3011111l; 3011112l; 3011113l; 3011114l;
|
||||
3011201l; 3011202l; 3011203l; 3011204l; 3011205l; 3011206l; 3011207l; 3011208l; 3011401l; 3011402l;
|
||||
3011403l; 3011404l; 3011405l; 3011406l; 3011407l; 3011408l; 3011501l; 3011502l; 3011503l; 3011504l;
|
||||
3011505l; 3011601l; 3011602l; 3011603l; 3011604l; 3011605l; 3011606l; 3011607l; 3011608l; 3011609l;
|
||||
3011610l; 3012001l; 4020101l; 4020102l; 4020103l; 4020104l; 4020105l; 4020106l; 4020107l; 4020108l;
|
||||
4020109l; 4020110l; 4020111l; 4020112l; 4020113l; 4020114l; 4010105l; 4010106l; 4010107l; 4010112l;
|
||||
4010113l; 4010131l; 4010115l; 4010116l; 4010121l; 4010122l; 4010123l; 4010124l; 4010125l; 4010126l;
|
||||
4010127l; 4010128l; 4010133l; 4010134l; 4010135l; 4010130l; 4010136l; 4010137l; 4015101l; 4015103l;
|
||||
4015102l; 4015202l; 4015203l; 4015204l; 4015301l; 4015302l; 4015303l; 4030001l; 4030002l; 4030003l;
|
||||
4030004l; 4030006l; 4030007l; 4030009l; 4030010l; 4040001l; 4040002l; 4040003l; 4040004l; 4040005l;
|
||||
4040006l; 4040052l; 4040007l; 4040008l; 4040051l; 4040009l; 4040010l; 4040011l; 4040012l; 4040053l;
|
||||
4040014l; 4040015l; 4040017l; 4040018l; 4040019l; 4040020l; 4040021l; 4040022l; 4040023l; 4040024l;
|
||||
4040100l; 4040189l; 4040190l; 4040101l; 4040151l; 4040154l; 4040102l; 4040103l; 4040153l; 4040104l;
|
||||
4040152l; 4040105l; 4040106l; 4040155l; 4040107l; 4040108l; 4040109l; 4040156l; 4040157l; 4040110l;
|
||||
4040114l; 4040115l; 4040158l; 4040159l; 4040160l; 4040161l; 4040162l; 4040116l; 4040169l; 4040163l;
|
||||
4040164l; 4040165l; 4040166l; 4040167l; 4040168l; 4040170l; 4040171l; 4040172l; 4040173l; 4040174l;
|
||||
4040175l; 4040176l; 4040177l; 4040178l; 4040179l; 4040180l; 4040181l; 4040182l; 4040183l; 4040184l;
|
||||
4040185l; 4040186l; 4040117l; 4040118l; 4040119l; 4040187l; 4040120l; 4040188l; 4040121l; 4040122l;
|
||||
4040123l; 4040124l; 4040125l; 4040126l; 4040127l; 4040128l; 4040129l; 4040130l; 4040201l; 4040202l;
|
||||
4040203l; 4040204l; 4040205l; 4040206l; 4040207l; 4040208l; 4040290l; 4040209l; 4040210l; 4040211l;
|
||||
4040212l; 4040213l; 4040214l; 4040215l; 4040216l; 4040217l; 4040218l; 4040219l; 4040220l; 4040221l;
|
||||
4040222l; 4040223l; 4040224l; 4040225l; 4040226l; 4040227l; 4040228l; 4040229l; 4040230l; 4040231l;
|
||||
4040240l; 4040241l; 4040242l; 4040244l; 4040245l; 4040246l; 4040247l; 4050005l; 4050007l; 4050008l;
|
||||
4050009l; 4050010l; 4050011l; 4050012l; 4050013l; 4050014l; 4050015l; 4050016l; 4050017l; 4050018l;
|
||||
4050019l; 4050020l; 4050021l; 4050022l; 4050023l; 4050024l; 4050025l; 4050026l; 4050027l; 4050028l;
|
||||
4050029l; 4050030l; 4050031l; 4050032l; 4050033l; 4050034l; 4050035l; 4050036l; 4050037l; 4072121l;
|
||||
4072122l; 4072123l; 4071311l; 4071312l; 4071313l; 4071320l; 4071321l; 4071322l; 4122100l; 4122101l;
|
||||
4122102l; 4122103l; 4081311l; 4081312l; 4081313l; 4081314l; 4081315l; 4081316l; 4081317l; 4081318l;
|
||||
8000001l; 8000002l; 8000101l; 8000102l; 8000104l; 8000105l; 8000131l; 8000132l; 8000133l; 8000134l;
|
||||
8000135l; 8000136l; 8000137l; 8000138l; 8000139l; 8000151l; 8000152l; 8000153l; 8000154l; 8000155l;
|
||||
8000156l; 8000157l; 8000158l; 8000159l; 8000161l; 8000162l; 8000170l; 8000171l; 8000172l; 8000173l;
|
||||
8000174l; 8000175l; 8000177l; 8000178l; 8000180l; 8000181l; 8000183l; 8000182l; 8000185l; 8000184l;
|
||||
8000186l; 8000187l; 8000188l; 8000189l; 8000201l; 8000202l; 8000203l; 8000204l; 8001201l; 8001202l;
|
||||
8001203l; 8001205l; 8001206l; 8001207l; 8001208l; 8001209l; 8001211l; 8001212l; 8001213l; 8001215l;
|
||||
8001216l; 8001219l; 8001220l; 8001223l; 8001224l; 8001225l; 8001226l; 8001227l; 8001204l; 8001210l;
|
||||
8001214l; 8001217l; 8001218l; 8001221l; 8001222l; 8001241l; 8001242l; 8001243l; 8001244l; 8001251l;
|
||||
8001252l; 8001253l; 8001254l; 8001255l; 8001261l; 8001262l; 8001263l; 8001264l; 8001265l; 8001266l;
|
||||
8001267l; 8001268l; 8011401l; 8002201l; 8002202l; 8002211l; 8002212l; 8002213l; 8002214l; 8002221l;
|
||||
8002222l; 8002231l; 8002232l; 8002233l; 8002234l; 8012101l; 8012102l; 8012103l; 8012104l; 8012105l;
|
||||
8012106l; 8012107l; 8012401l; 9999920l
|
||||
]
|
||||
|
||||
let on_get_mission_status pk =
|
||||
let dec = Pbrt.Decoder.of_string pk.body in
|
||||
let req = decode_pb_get_mission_status_cs_req dec in
|
||||
|
||||
let evt = List.map (fun id -> { id = id; progress = 1l; status = Mission_finish }) req.main_mission_id_list in
|
||||
let sub = List.map (fun id -> { id = id; progress = 1l; status = Mission_finish }) req.sub_mission_id_list in
|
||||
|
||||
let rsp = default_get_mission_status_sc_rsp
|
||||
~mission_event_status_list:evt
|
||||
~sub_mission_status_list:sub
|
||||
~finished_main_mission_id_list:finished_main_missions
|
||||
() in
|
||||
|
||||
pack cmd_get_mission_status_sc_rsp encode_pb_get_mission_status_sc_rsp rsp
|
22
gameserver/bin/handlers/player.ml
Normal file
22
gameserver/bin/handlers/player.ml
Normal file
|
@ -0,0 +1,22 @@
|
|||
open Cmdid
|
||||
open Packet
|
||||
open Protocol
|
||||
|
||||
let on_get_basic_info _pk = empty cmd_get_basic_info_sc_rsp
|
||||
|
||||
let on_player_heartbeat pk =
|
||||
let dec = Pbrt.Decoder.of_string pk.body in
|
||||
let req = decode_pb_player_heart_beat_cs_req dec in
|
||||
|
||||
let dec = Pbrt.Decoder.of_string (Base64.decode_exn "CDMQuQoa1gFDUy5Vbml0eUVuZ2luZS5HYW1lT2JqZWN0LkZpbmQoIlVJUm9vdC9BYm92ZURpYWxvZy9CZXRhSGludERpYWxvZyhDbG9uZSkiKTpHZXRDb21wb25lbnRJbkNoaWxkcmVuKHR5cGVvZihDUy5SUEcuQ2xpZW50LkxvY2FsaXplZFRleHQpKS50ZXh0ID0gIkxpbmdzaGFTUiBpcyBhIGZyZWUgYW5kIG9wZW4gc291cmNlIHNvZnR3YXJlLiBkaXNjb3JkLmdnL3JldmVyc2Vkcm9vbXMi") in
|
||||
let download_data = decode_pb_client_download_data dec in
|
||||
|
||||
let timestamp = Int64.of_float (Unix.gettimeofday() *. 1000.0) in
|
||||
let rsp = {
|
||||
retcode = 0l;
|
||||
client_time_ms = req.client_time_ms;
|
||||
server_time_ms = timestamp;
|
||||
download_data = Some download_data
|
||||
} in
|
||||
|
||||
pack cmd_player_heart_beat_sc_rsp encode_pb_player_heart_beat_sc_rsp rsp
|
54
gameserver/bin/handlers/scene.ml
Normal file
54
gameserver/bin/handlers/scene.ml
Normal file
|
@ -0,0 +1,54 @@
|
|||
open Cmdid
|
||||
open Protocol
|
||||
open Packet
|
||||
|
||||
let on_get_cur_scene_info _pk =
|
||||
let scene = default_scene_info
|
||||
~plane_id:20313l
|
||||
~floor_id:20313001l
|
||||
~entry_id:2031301l
|
||||
~game_mode_type:1l
|
||||
~scene_group_list:[
|
||||
{
|
||||
group_id = 0l;
|
||||
state = 1l;
|
||||
entity_list = [{
|
||||
entity_id = 0l;
|
||||
group_id = 0l;
|
||||
inst_id = 0l;
|
||||
motion = Some {
|
||||
pos = Some { x = 40748l; y = 192819l; z = 439218l; };
|
||||
rot = Some (default_vector ())
|
||||
};
|
||||
entity = Actor {
|
||||
base_avatar_id = 1222l;
|
||||
map_layer = 2l;
|
||||
uid = 1337l;
|
||||
avatar_type = Avatar_formal_type;
|
||||
}
|
||||
}]
|
||||
};
|
||||
{
|
||||
group_id = 186l;
|
||||
state = 1l;
|
||||
entity_list = [{
|
||||
entity_id = 1337l;
|
||||
group_id = 186l;
|
||||
inst_id = 300001l;
|
||||
motion = Some {
|
||||
pos = Some { x = 31440l; y = 192820l; z = 433790l; };
|
||||
rot = Some (default_vector ())
|
||||
};
|
||||
entity = Prop (default_scene_prop_info
|
||||
~prop_id:808l
|
||||
~prop_state:1l
|
||||
())
|
||||
}]
|
||||
}
|
||||
]
|
||||
() in
|
||||
|
||||
pack cmd_get_cur_scene_info_sc_rsp encode_pb_get_cur_scene_info_sc_rsp {
|
||||
retcode = 0l;
|
||||
scene = Some scene;
|
||||
}
|
1
gameserver/bin/main.ml
Normal file
1
gameserver/bin/main.ml
Normal file
|
@ -0,0 +1 @@
|
|||
let () = Gateway.listen "0.0.0.0" 23301
|
42
gameserver/bin/packet.ml
Normal file
42
gameserver/bin/packet.ml
Normal file
|
@ -0,0 +1,42 @@
|
|||
open Lwt
|
||||
open Lwt.Syntax
|
||||
|
||||
type packet = { cmd: int; head: string; body: string }
|
||||
|
||||
let read ic =
|
||||
let open Lwt_io in
|
||||
|
||||
let* head_magic = BE.read_int32 ic in
|
||||
assert (head_magic = 0x9D74C714l);
|
||||
|
||||
let* cmd = BE.read_int16 ic in
|
||||
let* head_size = BE.read_int16 ic in
|
||||
let* body_size = BE.read_int32 ic in
|
||||
let* head = read ~count:head_size ic in
|
||||
let* body = read ~count:(Int32.to_int body_size) ic in
|
||||
let* tail_magic = BE.read_int32 ic in
|
||||
assert (tail_magic = 0xD7A152C8l);
|
||||
|
||||
return {cmd = cmd; head = head; body = body}
|
||||
|
||||
let write oc pk =
|
||||
let open Lwt_io in
|
||||
|
||||
let* () = BE.write_int32 oc 0x9D74C714l in
|
||||
let* () = BE.write_int16 oc pk.cmd in
|
||||
let* () = BE.write_int16 oc (String.length pk.head) in
|
||||
let* () = BE.write_int32 oc (Int32.of_int (String.length pk.body)) in
|
||||
let* () = write oc pk.head in
|
||||
let* () = write oc pk.body in
|
||||
let* () = BE.write_int32 oc 0xD7A152C8l in
|
||||
let* () = flush oc in
|
||||
return_unit
|
||||
|
||||
let pack cmd en data =
|
||||
let encoder = Pbrt.Encoder.create () in
|
||||
en data encoder;
|
||||
|
||||
let buf = Pbrt.Encoder.to_string encoder in
|
||||
{ cmd = cmd; head = ""; body = buf; }
|
||||
|
||||
let empty cmd = { cmd = cmd; head = ""; body = "" }
|
170405
gameserver/bin/protocol.ml
Normal file
170405
gameserver/bin/protocol.ml
Normal file
File diff suppressed because it is too large
Load diff
52200
gameserver/bin/protocol.mli
Normal file
52200
gameserver/bin/protocol.mli
Normal file
File diff suppressed because it is too large
Load diff
14
gameserver/dune-project
Normal file
14
gameserver/dune-project
Normal file
|
@ -0,0 +1,14 @@
|
|||
(lang dune 3.16)
|
||||
|
||||
(name gameserver)
|
||||
|
||||
(generate_opam_files true)
|
||||
|
||||
(authors "xeondev")
|
||||
|
||||
(maintainers "xeondev")
|
||||
|
||||
(package
|
||||
(name gameserver)
|
||||
(synopsis "Game server emulator for Honkai: Star Rail")
|
||||
(depends ocaml dune lwt hex pbrt))
|
28
gameserver/gameserver.opam
Normal file
28
gameserver/gameserver.opam
Normal file
|
@ -0,0 +1,28 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
synopsis: "Game server emulator for Honkai: Star Rail"
|
||||
maintainer: ["xeondev"]
|
||||
authors: ["xeondev"]
|
||||
depends: [
|
||||
"ocaml"
|
||||
"dune" {>= "3.16"}
|
||||
"lwt"
|
||||
"pbrt"
|
||||
"base64"
|
||||
"hex"
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
["dune" "subst"] {dev}
|
||||
[
|
||||
"dune"
|
||||
"build"
|
||||
"-p"
|
||||
name
|
||||
"-j"
|
||||
jobs
|
||||
"@install"
|
||||
"@runtest" {with-test}
|
||||
"@doc" {with-doc}
|
||||
]
|
||||
]
|
2
gameserver/lib/dune
Normal file
2
gameserver/lib/dune
Normal file
|
@ -0,0 +1,2 @@
|
|||
(library
|
||||
(name gameserver))
|
BIN
mhypbase.dll
Executable file
BIN
mhypbase.dll
Executable file
Binary file not shown.
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 MiB |
10
sdkserver/bin/auth.ml
Normal file
10
sdkserver/bin/auth.ml
Normal file
|
@ -0,0 +1,10 @@
|
|||
module S = Tiny_httpd
|
||||
|
||||
let risky_api_check _req =
|
||||
S.Response.make_string (Ok "{\"data\": {}, \"message\": \"OK\", \"retcode\": 0}")
|
||||
|
||||
let mdk_shield_login _req =
|
||||
S.Response.make_string (Ok "{\"data\":{\"account\":{\"area_code\":\"**\",\"email\":\"LingshaSR\",\"country\":\"RU\",\"is_email_verify\":\"1\",\"token\":\"mostsecuretokenever\",\"uid\":\"1337\"},\"device_grant_required\":false,\"reactivate_required\":false,\"realperson_required\":false,\"safe_mobile_required\":false},\"message\":\"OK\",\"retcode\":0}")
|
||||
|
||||
let granter_login_v2 _req =
|
||||
S.Response.make_string (Ok "{\"data\":{\"account_type\":1,\"combo_id\":\"1337\",\"combo_token\":\"mostsecuretokenever\",\"data\":\"{\\\"guest\\\":false}\",\"heartbeat\":false,\"open_id\":\"1337\"},\"message\":\"OK\",\"retcode\":0}")
|
47
sdkserver/bin/dispatch.ml
Normal file
47
sdkserver/bin/dispatch.ml
Normal file
|
@ -0,0 +1,47 @@
|
|||
module S = Tiny_httpd
|
||||
open Protocol
|
||||
|
||||
let query_dispatch _req =
|
||||
let data = default_global_dispatch_data
|
||||
~retcode:0l
|
||||
~msg:"OK"
|
||||
~server_list:[{
|
||||
name = "lingsha_sr";
|
||||
display_name = "LingshaSR";
|
||||
title = "LingshaSR";
|
||||
env_type = "2";
|
||||
msg = "OK";
|
||||
dispatch_url = "http://127.0.0.1:21000/query_gateway";
|
||||
}] () in
|
||||
|
||||
let encoder = Pbrt.Encoder.create () in
|
||||
encode_pb_global_dispatch_data data encoder;
|
||||
|
||||
let buf = Pbrt.Encoder.to_string encoder in
|
||||
S.Response.make_string (Ok (Base64.encode_string buf))
|
||||
|
||||
let query_gateway _req =
|
||||
let data = default_gateserver
|
||||
~retcode:0l
|
||||
~ip:"127.0.0.1"
|
||||
~port:23301l
|
||||
~use_tcp:true
|
||||
~asset_bundle_url:"https://autopatchcn-ipv6.bhsr.com/asb/BetaLive/output_7663997_cd086af3f307"
|
||||
~ex_resource_url:"https://autopatchcn-ipv6.bhsr.com/design_data/BetaLive/output_7680597_a60760caba0f"
|
||||
~lua_url:"https://autopatchcn-ipv6.bhsr.com/lua/BetaLive/output_7668875_0231727458ad"
|
||||
~lua_version:"7668875"
|
||||
~fkenkkhlhhd:true
|
||||
~opgmnlinakc:true
|
||||
~mbdacjejamf:true
|
||||
~bgpcckkddmb:true
|
||||
~kjadmknddjl:true
|
||||
~gjaeghbeaio:true
|
||||
~lamjdogmfam:true
|
||||
~hafcipegpin:true
|
||||
() in
|
||||
|
||||
let encoder = Pbrt.Encoder.create () in
|
||||
encode_pb_gateserver data encoder;
|
||||
|
||||
let buf = Pbrt.Encoder.to_string encoder in
|
||||
S.Response.make_string (Ok (Base64.encode_string buf))
|
4
sdkserver/bin/dune
Normal file
4
sdkserver/bin/dune
Normal file
|
@ -0,0 +1,4 @@
|
|||
(executable
|
||||
(public_name sdkserver)
|
||||
(name main)
|
||||
(libraries tiny_httpd pbrt base64 sdkserver))
|
26
sdkserver/bin/main.ml
Normal file
26
sdkserver/bin/main.ml
Normal file
|
@ -0,0 +1,26 @@
|
|||
module S = Tiny_httpd
|
||||
open Printf
|
||||
|
||||
let () =
|
||||
let server = S.create ~addr:"0.0.0.0" ~port:21000 () in
|
||||
|
||||
(* dispatch routes *)
|
||||
S.add_route_handler ~meth:`GET server
|
||||
S.Route.(exact_path "query_dispatch" return) Dispatch.query_dispatch;
|
||||
S.add_route_handler ~meth:`GET server
|
||||
S.Route.(exact_path "query_gateway" return) Dispatch.query_gateway;
|
||||
|
||||
(* sdk routes *)
|
||||
S.add_route_handler ~meth:`POST server
|
||||
S.Route.(exact_path "account/risky/api/check" return) Auth.risky_api_check;
|
||||
S.add_route_handler ~meth:`POST server
|
||||
S.Route.(exact_path "hkrpg_global/mdk/shield/api/login" return) Auth.mdk_shield_login;
|
||||
S.add_route_handler ~meth:`POST server
|
||||
S.Route.(exact_path "hkrpg_global/mdk/shield/api/verify" return) Auth.mdk_shield_login;
|
||||
S.add_route_handler ~meth:`POST server
|
||||
S.Route.(exact_path "hkrpg_global/combo/granter/login/v2/login" return) Auth.granter_login_v2;
|
||||
|
||||
printf "SDK Server is listening at %s:%d\n%!" (S.addr server) (S.port server);
|
||||
match S.run server with
|
||||
| Ok () -> ()
|
||||
| Error e -> raise e
|
1009
sdkserver/bin/protocol.ml
Normal file
1009
sdkserver/bin/protocol.ml
Normal file
File diff suppressed because it is too large
Load diff
199
sdkserver/bin/protocol.mli
Normal file
199
sdkserver/bin/protocol.mli
Normal file
|
@ -0,0 +1,199 @@
|
|||
|
||||
(** Code for protocol.proto *)
|
||||
|
||||
(* generated from "./protocol.proto", do not edit *)
|
||||
|
||||
|
||||
|
||||
(** {2 Types} *)
|
||||
|
||||
type server_data = {
|
||||
name : string;
|
||||
display_name : string;
|
||||
dispatch_url : string;
|
||||
env_type : string;
|
||||
title : string;
|
||||
msg : string;
|
||||
}
|
||||
|
||||
type global_dispatch_data = {
|
||||
retcode : int32;
|
||||
msg : string;
|
||||
ajkbajlebhn : string;
|
||||
server_list : server_data list;
|
||||
odbdlipeoog : string;
|
||||
}
|
||||
|
||||
type gateserver = {
|
||||
cmelkdaaapf : bool;
|
||||
ophmlpkgkij : bool;
|
||||
mmcjggcenpp : string;
|
||||
pllenlninnh : string;
|
||||
lamjdogmfam : bool;
|
||||
bblkofdgpap : string;
|
||||
ephafkmpmif : string;
|
||||
gmdfmaapebc : string;
|
||||
mlcpkfihkko : int64;
|
||||
bgpcckkddmb : bool;
|
||||
ex_resource_url : string;
|
||||
nkfnaojjlph : string;
|
||||
hkdmdpmahem : string;
|
||||
onkpibmdmpi : string;
|
||||
fbobagpbbha : string;
|
||||
mjjbccmcplk : string;
|
||||
port : int32;
|
||||
anegjdlagll : string;
|
||||
gepfimnioke : bool;
|
||||
lpnoekiaocp : string;
|
||||
fgkgddonpkm : string;
|
||||
nejihdfafbe : int32;
|
||||
hafcipegpin : bool;
|
||||
kghpigijmbp : string;
|
||||
fpglgbgjmjc : string;
|
||||
molbpmljolo : string;
|
||||
asset_bundle_url : string;
|
||||
kjadmknddjl : bool;
|
||||
khclmhjlopk : string list;
|
||||
lua_version : string;
|
||||
okplkdhmohc : string;
|
||||
ooeapiaafnb : string;
|
||||
jelgnociekj : string;
|
||||
hhpakondiob : int64;
|
||||
opgmnlinakc : bool;
|
||||
begfcjlkmob : bool;
|
||||
nnhognglfbd : string;
|
||||
retcode : int32;
|
||||
kgljfhdhdek : string;
|
||||
cjnjnfglick : int32;
|
||||
ncdioakalen : string;
|
||||
ip : string;
|
||||
gediongpdha : bool;
|
||||
mbdacjejamf : bool;
|
||||
lua_url : string;
|
||||
dmdahpindno : string;
|
||||
gjaeghbeaio : bool;
|
||||
ddohlaegeah : int32;
|
||||
bfoekehoejp : string;
|
||||
chnmpglhncm : string;
|
||||
pggjoogfgfc : string;
|
||||
dklchemciai : bool;
|
||||
migeegecjcb : string;
|
||||
ciinblfopda : string;
|
||||
fkenkkhlhhd : bool;
|
||||
hjbndbbicdo : string;
|
||||
fggmipmoook : string;
|
||||
use_tcp : bool;
|
||||
imffkkjpojc : string;
|
||||
}
|
||||
|
||||
|
||||
(** {2 Basic values} *)
|
||||
|
||||
val default_server_data :
|
||||
?name:string ->
|
||||
?display_name:string ->
|
||||
?dispatch_url:string ->
|
||||
?env_type:string ->
|
||||
?title:string ->
|
||||
?msg:string ->
|
||||
unit ->
|
||||
server_data
|
||||
(** [default_server_data ()] is the default value for type [server_data] *)
|
||||
|
||||
val default_global_dispatch_data :
|
||||
?retcode:int32 ->
|
||||
?msg:string ->
|
||||
?ajkbajlebhn:string ->
|
||||
?server_list:server_data list ->
|
||||
?odbdlipeoog:string ->
|
||||
unit ->
|
||||
global_dispatch_data
|
||||
(** [default_global_dispatch_data ()] is the default value for type [global_dispatch_data] *)
|
||||
|
||||
val default_gateserver :
|
||||
?cmelkdaaapf:bool ->
|
||||
?ophmlpkgkij:bool ->
|
||||
?mmcjggcenpp:string ->
|
||||
?pllenlninnh:string ->
|
||||
?lamjdogmfam:bool ->
|
||||
?bblkofdgpap:string ->
|
||||
?ephafkmpmif:string ->
|
||||
?gmdfmaapebc:string ->
|
||||
?mlcpkfihkko:int64 ->
|
||||
?bgpcckkddmb:bool ->
|
||||
?ex_resource_url:string ->
|
||||
?nkfnaojjlph:string ->
|
||||
?hkdmdpmahem:string ->
|
||||
?onkpibmdmpi:string ->
|
||||
?fbobagpbbha:string ->
|
||||
?mjjbccmcplk:string ->
|
||||
?port:int32 ->
|
||||
?anegjdlagll:string ->
|
||||
?gepfimnioke:bool ->
|
||||
?lpnoekiaocp:string ->
|
||||
?fgkgddonpkm:string ->
|
||||
?nejihdfafbe:int32 ->
|
||||
?hafcipegpin:bool ->
|
||||
?kghpigijmbp:string ->
|
||||
?fpglgbgjmjc:string ->
|
||||
?molbpmljolo:string ->
|
||||
?asset_bundle_url:string ->
|
||||
?kjadmknddjl:bool ->
|
||||
?khclmhjlopk:string list ->
|
||||
?lua_version:string ->
|
||||
?okplkdhmohc:string ->
|
||||
?ooeapiaafnb:string ->
|
||||
?jelgnociekj:string ->
|
||||
?hhpakondiob:int64 ->
|
||||
?opgmnlinakc:bool ->
|
||||
?begfcjlkmob:bool ->
|
||||
?nnhognglfbd:string ->
|
||||
?retcode:int32 ->
|
||||
?kgljfhdhdek:string ->
|
||||
?cjnjnfglick:int32 ->
|
||||
?ncdioakalen:string ->
|
||||
?ip:string ->
|
||||
?gediongpdha:bool ->
|
||||
?mbdacjejamf:bool ->
|
||||
?lua_url:string ->
|
||||
?dmdahpindno:string ->
|
||||
?gjaeghbeaio:bool ->
|
||||
?ddohlaegeah:int32 ->
|
||||
?bfoekehoejp:string ->
|
||||
?chnmpglhncm:string ->
|
||||
?pggjoogfgfc:string ->
|
||||
?dklchemciai:bool ->
|
||||
?migeegecjcb:string ->
|
||||
?ciinblfopda:string ->
|
||||
?fkenkkhlhhd:bool ->
|
||||
?hjbndbbicdo:string ->
|
||||
?fggmipmoook:string ->
|
||||
?use_tcp:bool ->
|
||||
?imffkkjpojc:string ->
|
||||
unit ->
|
||||
gateserver
|
||||
(** [default_gateserver ()] is the default value for type [gateserver] *)
|
||||
|
||||
|
||||
(** {2 Protobuf Encoding} *)
|
||||
|
||||
val encode_pb_server_data : server_data -> Pbrt.Encoder.t -> unit
|
||||
(** [encode_pb_server_data v encoder] encodes [v] with the given [encoder] *)
|
||||
|
||||
val encode_pb_global_dispatch_data : global_dispatch_data -> Pbrt.Encoder.t -> unit
|
||||
(** [encode_pb_global_dispatch_data v encoder] encodes [v] with the given [encoder] *)
|
||||
|
||||
val encode_pb_gateserver : gateserver -> Pbrt.Encoder.t -> unit
|
||||
(** [encode_pb_gateserver v encoder] encodes [v] with the given [encoder] *)
|
||||
|
||||
|
||||
(** {2 Protobuf Decoding} *)
|
||||
|
||||
val decode_pb_server_data : Pbrt.Decoder.t -> server_data
|
||||
(** [decode_pb_server_data decoder] decodes a [server_data] binary value from [decoder] *)
|
||||
|
||||
val decode_pb_global_dispatch_data : Pbrt.Decoder.t -> global_dispatch_data
|
||||
(** [decode_pb_global_dispatch_data decoder] decodes a [global_dispatch_data] binary value from [decoder] *)
|
||||
|
||||
val decode_pb_gateserver : Pbrt.Decoder.t -> gateserver
|
||||
(** [decode_pb_gateserver decoder] decodes a [gateserver] binary value from [decoder] *)
|
14
sdkserver/dune-project
Normal file
14
sdkserver/dune-project
Normal file
|
@ -0,0 +1,14 @@
|
|||
(lang dune 3.16)
|
||||
|
||||
(name sdkserver)
|
||||
|
||||
(generate_opam_files true)
|
||||
|
||||
(authors "xeondev")
|
||||
|
||||
(maintainers "xeondev")
|
||||
|
||||
(package
|
||||
(name sdkserver)
|
||||
(synopsis "SDK Server emulator for Honkai: Star Rail")
|
||||
(depends ocaml dune tiny_httpd base64 pbrt))
|
2
sdkserver/lib/dune
Normal file
2
sdkserver/lib/dune
Normal file
|
@ -0,0 +1,2 @@
|
|||
(library
|
||||
(name sdkserver))
|
27
sdkserver/sdkserver.opam
Normal file
27
sdkserver/sdkserver.opam
Normal file
|
@ -0,0 +1,27 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
synopsis: "SDK Server emulator for Honkai: Star Rail"
|
||||
maintainer: ["xeondev"]
|
||||
authors: ["xeondev"]
|
||||
depends: [
|
||||
"ocaml"
|
||||
"dune" {>= "3.16"}
|
||||
"tiny_httpd"
|
||||
"base64"
|
||||
"pbrt"
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
["dune" "subst"] {dev}
|
||||
[
|
||||
"dune"
|
||||
"build"
|
||||
"-p"
|
||||
name
|
||||
"-j"
|
||||
jobs
|
||||
"@install"
|
||||
"@runtest" {with-test}
|
||||
"@doc" {with-doc}
|
||||
]
|
||||
]
|
Loading…
Reference in a new issue