diff --git a/GameControl/GlobalAPI/define.go b/GameControl/GlobalAPI/define.go
deleted file mode 100644
index c207d0633..000000000
--- a/GameControl/GlobalAPI/define.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package GlobalAPI
-
-import (
- "phoenixbuilder/GameControl/ResourcesControlCenter"
- "phoenixbuilder/minecraft/protocol/packet"
-)
-
-// 描述客户端的基本信息
-type BotInfo struct {
- BotName string // 客户端的游戏昵称
- BotIdentity string // 客户端的唯一标识符 [当前还未使用]
- BotUniqueID int64 // 客户端的唯一 ID [当前还未使用]
- BotRunTimeID uint64 // 客户端的运行时 ID
-}
-
-// 用于 PhoenixBuilder 与租赁服交互。
-// 此结构体下的实现将允许您与租赁服进行交互操作,例如打开容器等
-type GlobalAPI struct {
- // 用于向租赁服发送数据包的函数
- WritePacket func(packet.Packet) error
- // 存储客户端的基本信息
- BotInfo BotInfo
- // PhoenixBuilder 的各类公用资源
- Resources *ResourcesControlCenter.Resources
-}
diff --git a/GameControl/GlobalAPI/getQuerytargetInfo.go b/GameControl/GlobalAPI/getQuerytargetInfo.go
deleted file mode 100644
index a3dc2f40c..000000000
--- a/GameControl/GlobalAPI/getQuerytargetInfo.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package GlobalAPI
-
-import (
- "encoding/json"
- "fmt"
- "phoenixbuilder/minecraft/protocol/packet"
-)
-
-// 用于描述单个 querytarget 结果的结构体
-type QuerytargetInfo struct {
- Dimension byte
- Position [3]float32
- UniqueId string
- YRot float32
-}
-
-// 解析 querytarget 命令的返回值为列表,因为同一时刻可以查询多个实体的相关数据。
-// 列表内单个数据的数据类型为 QuerytargetInfo 结构体
-func (g *GlobalAPI) ParseQuerytargetInfo(pk packet.CommandOutput) ([]QuerytargetInfo, error) {
- ans := []QuerytargetInfo{}
- // 初始化
- if pk.SuccessCount <= 0 || len(pk.OutputMessages[0].Parameters) <= 0 {
- return []QuerytargetInfo{}, nil
- }
- // 如果命令失败或者未能找到任何可以解析的信息
- datas := pk.OutputMessages[0].Parameters[0]
- var datasDecodeAns []interface{}
- err := json.Unmarshal([]byte(datas), &datasDecodeAns)
- if err != nil {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: %v", err)
- }
- // 解析 JSON 数据
- for _, value := range datasDecodeAns {
- newStruct := QuerytargetInfo{}
- // 初始化
- val, normal := value.(map[string]interface{})
- if !normal {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Could not convert value into map[string]interface{}; value = %#v", value)
- }
- // 将列表中的被遍历元素解析为 map[string]interface{}
- _, ok := val["dimension"]
- if !ok {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"dimension\"]; val = %#v", val)
- }
- dimension, normal := val["dimension"].(float64)
- if !normal {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"dimension\"]; val = %#v", val)
- }
- newStruct.Dimension = byte(dimension)
- // dimension
- _, ok = val["position"]
- if !ok {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"]; val = %#v", val)
- }
- position, normal := val["position"].(map[string]interface{})
- if normal {
- _, ok := position["x"]
- if !ok {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"][\"x\"]; val[\"position\"] = %#v", position)
- }
- x, normal := position["x"].(float64)
- if !normal {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"][\"x\"]; val[\"position\"] = %#v", position)
- }
- newStruct.Position = [3]float32{float32(x), 0, 0}
- // posx
- _, ok = position["y"]
- if !ok {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"][\"y\"]; val[\"position\"] = %#v", position)
- }
- y, normal := position["y"].(float64)
- if !normal {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"][\"y\"]; val[\"position\"] = %#v", position)
- }
- newStruct.Position[1] = float32(y)
- // posy
- _, ok = position["z"]
- if !ok {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"][\"z\"]; val[\"position\"] = %#v", position)
- }
- z, normal := position["z"].(float64)
- if !normal {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"][\"z\"]; val[\"position\"] = %#v", position)
- }
- newStruct.Position[2] = float32(z)
- // posz
- } else {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"position\"]; val = %#v", val)
- }
- // position
- _, ok = val["uniqueId"]
- if !ok {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"uniqueId\"]; val = %#v", val)
- }
- uniqueId, normal := val["uniqueId"].(string)
- if !normal {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"uniqueId\"]; val = %#v", val)
- }
- newStruct.UniqueId = uniqueId
- // uniqueId
- _, ok = val["yRot"]
- if !ok {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"yRot\"]; val = %#v", val)
- }
- yRot, normal := val["yRot"].(float64)
- if !normal {
- return []QuerytargetInfo{}, fmt.Errorf("ParseQuerytargetInfo: Crashed in val[\"yRot\"]; val = %#v", val)
- }
- newStruct.YRot = float32(yRot)
- // yRot
- ans = append(ans, newStruct)
- // append struct
- }
- return ans, nil
- // 返回值
-}
diff --git a/GameControl/GlobalAPI/sendcommand.go b/GameControl/GlobalAPI/sendcommand.go
deleted file mode 100644
index 3894161dc..000000000
--- a/GameControl/GlobalAPI/sendcommand.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package GlobalAPI
-
-import (
- "fmt"
- "phoenixbuilder/minecraft/protocol"
- "phoenixbuilder/minecraft/protocol/packet"
-
- "github.com/google/uuid"
-)
-
-// 向租赁服发送 Sizukana 命令且无视返回值。
-// 当 sendDimensionalCmd 为真时,
-// 将使用 execute 更换命令执行环境为机器人所在的环境
-func (g *GlobalAPI) SendSettingsCommand(
- command string,
- sendDimensionalCmd bool,
-) error {
- if sendDimensionalCmd {
- command = fmt.Sprintf(
- `execute @a[name="%v"] ~ ~ ~ %v`,
- g.BotInfo.BotName,
- command,
- )
- }
- err := g.WritePacket(&packet.SettingsCommand{
- CommandLine: command,
- SuppressOutput: true,
- })
- if err != nil {
- return fmt.Errorf("SendSettingsCommand: %v", err)
- }
- return nil
-}
-
-// 以 origin 的身份向租赁服发送命令且无视返回值。
-// 属于私有实现
-func (g *GlobalAPI) sendCommandPrivate(
- command string,
- uniqueId uuid.UUID,
- origin uint32,
-) error {
- requestId, _ := uuid.Parse("96045347-a6a3-4114-94c0-1bc4cc561694")
- err := g.WritePacket(&packet.CommandRequest{
- CommandLine: command,
- CommandOrigin: protocol.CommandOrigin{
- Origin: origin,
- UUID: uniqueId,
- RequestID: requestId.String(),
- },
- Internal: false,
- UnLimited: false,
- })
- if err != nil {
- return fmt.Errorf("sendCommandPrivate: %v", err)
- }
- return nil
-}
-
-// 以 origin 的身份向租赁服发送命令并且取得响应体。
-// 属于私有实现
-func (g *GlobalAPI) sendCMDWithRespPrivate(
- command string,
- origin uint32,
-) (packet.CommandOutput, error) {
- uniqueId := generateUUID()
- err := g.Resources.Command.WriteRequest(uniqueId)
- if err != nil {
- return packet.CommandOutput{}, fmt.Errorf("sendCMDWithRespPrivate: %v", err)
- }
- // 写入请求到等待队列
- err = g.sendCommandPrivate(command, uniqueId, origin)
- if err != nil {
- return packet.CommandOutput{}, fmt.Errorf("sendCMDWithRespPrivate: %v", err)
- }
- // 发送命令
- ans, err := g.Resources.Command.LoadResponceAndDelete(uniqueId)
- if err != nil {
- return packet.CommandOutput{}, fmt.Errorf("sendCMDWithRespPrivate: %v", err)
- }
- // 等待租赁服响应命令请求并取得命令请求的返回值
- return ans, nil
- // 返回值
-}
-
-// 以玩家的身份向租赁服发送命令且无视返回值
-func (g *GlobalAPI) SendCommand(command string, uniqueId uuid.UUID) error {
- err := g.sendCommandPrivate(command, uniqueId, protocol.CommandOriginPlayer)
- if err != nil {
- return fmt.Errorf("SendCommand: %v", err)
- }
- return nil
-}
-
-// 向租赁服发送 WS 命令且无视返回值
-func (g *GlobalAPI) SendWSCommand(command string, uniqueId uuid.UUID) error {
- err := g.sendCommandPrivate(command, uniqueId, protocol.CommandOriginAutomationPlayer)
- if err != nil {
- return fmt.Errorf("SendWSCommand: %v", err)
- }
- return nil
-}
-
-// 以玩家的身份向租赁服发送命令且获取返回值
-func (g *GlobalAPI) SendCommandWithResponce(command string) (packet.CommandOutput, error) {
- resp, err := g.sendCMDWithRespPrivate(command, protocol.CommandOriginPlayer)
- if err != nil {
- return packet.CommandOutput{}, fmt.Errorf("SendCommandWithResponce: %v", err)
- }
- return resp, nil
-}
-
-// 向租赁服发送 WS 命令且获取返回值
-func (g *GlobalAPI) SendWSCommandWithResponce(command string) (packet.CommandOutput, error) {
- resp, err := g.sendCMDWithRespPrivate(command, protocol.CommandOriginAutomationPlayer)
- if err != nil {
- return packet.CommandOutput{}, fmt.Errorf("SendWSCommandWithResponce: %v", err)
- }
- return resp, nil
-}
diff --git a/Makefile b/Makefile
index c0d93ab48..fede29be2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.PHONY: current all current-v8 current-arm64-executable ios-executable ios-v8-executable ios-lib ish-executable macos macos-v8 android-executable-armv7 android-executable-arm64 android-executable-x86_64 android-executable-x86 windows-executable windows-executable-x86 windows-executable-x86_64 freebsd-executable freebsd-executable-x86 freebsd-executable-x86_64 freebsd-executable-arm64 netbsd-executable netbsd-executable-x86 netbsd-executable-x86_64 netbsd-executable-arm64 netbsd-executable netbsd-executable-x86 netbsd-executable-x86_64 netbsd-executable-arm64 openwrt-mt7620-mipsel_24kc
+.PHONY: current all current-v8 current-arm64-executable ios-executable ios-v8-executable ish-executable macos macos-v8 android-executable-armv7 android-executable-arm64 android-executable-x86_64 android-executable-x86 windows-executable windows-executable-x86 windows-executable-x86_64 freebsd-executable freebsd-executable-x86 freebsd-executable-x86_64 freebsd-executable-arm64 netbsd-executable netbsd-executable-x86 netbsd-executable-x86_64 netbsd-executable-arm64 netbsd-executable netbsd-executable-x86 netbsd-executable-x86_64 netbsd-executable-arm64 openwrt-mt7620-mipsel_24kc
TARGETS:=build/ current current-no-readline current-v8
PACKAGETARGETS:=
ifeq ($(shell uname | grep "Darwin" > /dev/null ; echo $${?}),0)
@@ -6,13 +6,13 @@ ifeq ($(shell uname -m | grep -E "iPhone|iPad|iPod" > /dev/null ; echo $${?}),0)
IOS_STRIP=/usr/bin/strip
LIPO=/usr/bin/lipo
LDID=/usr/bin/ldid
-TARGETS:=${TARGETS} ios-executable ios-v8-executable ios-lib
+TARGETS:=${TARGETS} ios-executable ios-v8-executable
else
IOS_STRIP=$(shell xcrun --sdk iphoneos -f strip)
IOS_OBJCOPY=$(shell xcrun --sdk iphoneos -f objcopy)
LDID=ldid2
LIPO=/usr/bin/lipo
-TARGETS:=${TARGETS} macos ios-v8-executable ios-executable ios-lib
+TARGETS:=${TARGETS} macos ios-v8-executable ios-executable
endif
PACKAGETARGETS:=${PACKAGETARGETS} package/ios
else
@@ -30,7 +30,7 @@ endif
### *-----------------------------------* ###
ifneq (${THEOS},)
- TARGETS:=${TARGETS} ios-executable ios-lib ios-v8-executable macos macos-v8
+ TARGETS:=${TARGETS} ios-executable ios-v8-executable macos macos-v8
PACKAGETARGETS:=${PACKAGETARGETS} package/ios
endif
ifneq ($(wildcard ${HOME}/android-ndk-r20b),)
@@ -77,7 +77,6 @@ current-v8: build/phoenixbuilder-v8
current-arm64-executable: build/phoenixbuilder-aarch64
ios-executable: build/phoenixbuilder-ios-executable
ios-v8-executable: build/phoenixbuilder-v8-ios-executable
-ios-lib: build/phoenixbuilder-ios-static.a
ish-executable: build/phoenixbuilder-ish-executable
macos: build/phoenixbuilder-macos
macos-v8: build/phoenixbuilder-v8-macos
@@ -144,8 +143,6 @@ build/phoenixbuilder-v8: build/ ${SRCS_GO}
CGO_CFLAGS=${CGO_DEF}" -DWITH_V8" CGO_ENABLED=1 go build -tags "with_v8 ${APPEND_GO_TAGS}" -trimpath -ldflags "-s -w" -o build/phoenixbuilder-v8
build/libexternal_functions_provider.so: build/ io/external_functions_provider/provider.c
gcc -shared io/external_functions_provider/provider.c -o build/libexternal_functions_provider.so
-build/phoenixbuilder-static.a: build/ build/libexternal_functions_provider.so ${SRCS_GO}
- CGO_CFLAGS=${CGO_DEF} CGO_LDFLAGS="-Lbuild -lexternal_functions_provider" CGO_ENABLED=1 go build -trimpath -buildmode=c-archive -ldflags "-s -w" -tags "no_readline,is_tweak ${APPEND_GO_TAGS}" -o build/phoenixbuilder-static.a
build/phoenixbuilder-aarch64: build/ ${SRCS_GO}
cd depends/stub&&make clean&&make CC=/usr/bin/aarch64-linux-gnu-gcc&&cd -
GODEBUG=madvdontneed=1 CGO_CFLAGS=${CGO_DEF} CC=/usr/bin/aarch64-linux-gnu-gcc CGO_ENABLED=1 GOARCH=arm64 go build -tags use_aarch64_linux_rl -trimpath -ldflags "-s -w" -o build/phoenixbuilder-aarch64
@@ -159,8 +156,6 @@ build/phoenixbuilder-v8-ios-executable: build/ ${SRCS_GO}
${LDID} -Sios-ent.xml build/phoenixbuilder-v8-ios-executable
build/libexternal_functions_provider.dylib: build/ io/external_functions_provider/provider.c
`pwd`/archs/ios.sh io/external_functions_provider/provider.c -shared -o build/libexternal_functions_provider.dylib
-build/phoenixbuilder-ios-static.a: build/ build/libexternal_functions_provider.dylib ${SRCS_GO}
- CGO_CFLAGS=${CGO_DEF} CGO_LDFLAGS="-Lbuild -lexternal_functions_provider" CC=`pwd`/archs/ios.sh CGO_ENABLED=1 GOOS=ios GOARCH=arm64 go build -buildmode=c-archive -trimpath -ldflags "-s -w -extar ${THEOS}/toolchain/linux/iphone/bin/ar" -tags is_tweak,no_readline -o build/phoenixbuilder-ios-static.a
build/phoenixbuilder-ish-executable: build/ ${SRCS_GO}
cd depends/stub&&make clean&&make CC="${HOME}/i686-unknown-linux-musl/bin/i686-unknown-linux-musl-gcc --sysroot=`pwd`/../buildroot/ish -L`pwd`/../buildroot/ish/usr/lib" && cd -
GODEBUG=madvdontneed=1 CGO_CFLAGS=${CGO_DEF} CC="${HOME}/i686-unknown-linux-musl/bin/i686-unknown-linux-musl-gcc --sysroot=`pwd`/depends/buildroot/ish" CGO_ENABLED=1 GOOS=linux GOARCH=386 go build -tags "ish" -trimpath -ldflags "-s -w" -o build/phoenixbuilder-ish-executable
diff --git a/docs/bdump/bdump.md b/docs/bdump/bdump.md
index b85dd2234..716c15f51 100644
--- a/docs/bdump/bdump.md
+++ b/docs/bdump/bdump.md
@@ -1,45 +1,43 @@
# BDump File Format
-BDump v3 is a file format for storing Minecraft's structures. It is made of different commands that indicate the constructing process.
+BDump v3 is a file format for storing Minecraft's structures, which is made of a set of commands indicating the constructing process.
-By writing the ids that represent each blocks in a specific order is a workable plan that reduces the file size, but this would allow a large amount of unexpected air blocks that increasing the file size so we implemented a new format which has a pointer that indicates where the "brush" is, the file is a set of commands that tells the "brush" how to move, and where to place blocks. Within this file format, air blocks can be simply skipped by a move command so files can be smaller.
+By writing the IDs of each blocks in a specific order is a workable plan for reducing the file size, but this would leave a large amount of unexpected air blocks increasing the file size. Therefore this format holding a pointer indicating the position of the "brush" is implemented.
## Basic File Structure
-BDump v3 file's extension is `.bdx`, and the general header of it is `BD@`, which stands for that the file was compressed with brotli compression algorithm (the compress quality phoenixbuilder uses is 6). Note that there's also a header `BDZ` that stands for the file was compressed with gzip compression algorithm, which is no longer supported by PhoenixBuilder today since it has been deprecated for a long time and it's hard to find this type's file again. We define such kind of header as "compression header" and the content after it is compressed with the compression algorithm it indicates.
+BDump v3 file's recommended extension is `.bdx`, whose general header is `BD@`, standing for a compression in `brotli` algorithm (default compressing quality: 6). Note that the header `BDZ` standing for a `gzip` compressed file is also possible, but is no longer supported by PhoenixBuilder since it has been deprecated for a long time and it's hard to find this type's file again. The content after the compression header is the data compressed with the compression algorithm it indicates.
-> Tip: BDump v2's extension is `.bdp` and the header is `BDMPS\0\x02\0`.
+> Note: BDump v2's extension is `.bdp` and the header is `BDMPS\0\x02\0`.
-The header of the compressed content is `BDX\0`, and the author's player name that terminated with `\0` is followed right after it. Then the content after it is the command with arguments that written one-by-one tightly. Each command id would take 1 byte of space, like what an `unsigned char` do.
+The header of the compressed content is `BDX\0`, and the author's player name terminated by `\0` following right after it (deprecated). The content after it is the command with arguments that written one-by-one tightly. Each command id would take 1 byte of space, like what an `unsigned char` do.
-All the operations depend a `Vec3` value that represents the current position of the "brush".
+All the operations depend on a shared `Vec3` value representing the current position of the "brush".
-Let's see the list of commands first.
+The list of commands is shown below.
> Note: Integers would be written in **big endian**.
>
-> What is the difference of little endian and big endian?
->
> For example, an int32 number in little endian, `1`, is `01 00 00 00` in the memory, and the memory of an int32 number `1` in big endian is `00 00 00 01`.
Type definition:
-* {int}: a number that can be positive, negative or zero.
-* {unsigned int}: a number that can be positive or zero.
-* `char`: an {int} value with 1 byte long.
-* `unsigned char`: an {unsigned int} value with 1 byte long.
-* `short`: an {int} value with 2 bytes long.
-* `unsigned short`: an {unsigned int} value with 2 bytes long.
-* `int32_t`: an {int} value with 4 bytes long.
-* `uint32_t`: an {unsigned int} value with 4 bytes long.
-* `char *`: a string that terminated with `\0` (encoding is utf-8).
+* {int}: an integer that can be positive, negative or zero.
+* {unsigned int}: an integer that can be positive or zero.
+* `char`: an 1-byte-long {int} value.
+* `unsigned char`: an 1-byte-long {unsigned int} value.
+* `short`/`int16_t`: a 2-byte-long {int} value.
+* `unsigned short`/`uint16_t`: a 2-byte-long {unsigned int} value.
+* `int32_t`: a 4-byte-long {int} value.
+* `uint32_t`: a 4-byte-long {unsigned int} value.
+* `char *`: a string terminated by `\0` (utf-8 encoded).
* `int`: alias of `int32_t`
* `unsigned int`: alias of `uint32_t`
-* `bool`: a value that can be either `true(1)` or `false(0)`, 1 byte long.
+* `bool`: an 1-byte-long value that can be either `true(1)` or `false(0)`.
| ID | Internal name | Description | Arguments |
| ----------------- | --------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| 1 | `CreateConstantString` | Add the specified string to the palette, and the ID of the string is sorted in the term of the command called, e.g. the ID when assigning the first string given is `0`, and the ID of the second time is `1`. The maximum count of strings is `65536`. | `char *constantString` |
+| 1 | `CreateConstantString` | Add the specified string to the palette, whose ID is sorted by the order of having the command called, e.g. the ID of the first constant string given is `0`, and the ID of the second one is `1`. The maximum count of strings is `65536`. | `char *constantString` |
| 2 | **DEPRECATED and REMOVED** | - | - |
| 3 | **DEPRECATED and REMOVED** | - | - |
| 4 | **DEPRECATED and REMOVED** | - | - |
@@ -83,7 +81,7 @@ Type definition:
| 88, `'X'`, `0x58` | `Terminate` | Stop reading. Note that although the general end is "XE" (2 bytes long), a 'X' (1 byte long) character is enough. | - |
| 90, `0x5A` | `isSigned` (fake command) | A command that functions a little different with other commands, its argument is the previous byte of it, would only appear in the end of the file. An invalid signature would prevent PhoenixBuilder from constructing the structure. See paragraph `Signing` for reference. | `unsigned char signatureSize` |
-The list above is all the commands of the bdump v4 till 2022-1-29.
+The list above is all the commands of the bdump v4 till June 26th of 2023.
For the `struct ChestData` data format:
diff --git a/fastbuilder/args/args.c b/fastbuilder/args/args.c
index 11674f204..ca13af0aa 100644
--- a/fastbuilder/args/args.c
+++ b/fastbuilder/args/args.c
@@ -8,6 +8,13 @@
#include
#endif
#include
+#include
+#ifdef WIN32
+#ifndef __MINGW32__
+#error "This file uses gcc-specific features, please consider switching to mingw gcc."
+#endif
+#include
+#endif
#ifndef FB_VERSION
#define FB_VERSION "(CUSTOMIZED)"
@@ -16,37 +23,41 @@
#warning "It seems that you're building PhoenixBuilder with plain `go build` command, it is highly recommended to use `make current` instead."
#endif
+struct go_string {
+ char *buf;
+ uint64_t length;
+};
+
+#define EMPTY_GOSTRING {"",0}
+
char args_isDebugMode=0;
-char args_disableHashCheck=0;
-char replaced_auth_server=0;
-char *newAuthServer;
-char args_muteWorldChat=0;
-char args_noPyRpc=1;
-char use_startup_script=0;
-char *startup_script;
-char specified_server=0;
-char *server_code;
-char *server_password="";
-char custom_token=0;
-char *token_content;
-char *externalListenAddr="";
-char *capture_output_file="";
+char args_disableVersionCheck=0;
+struct go_string newAuthServer={
+ "wss://api.fastbuilder.pro:2053/",
+ 31
+};
+struct go_string startup_script=EMPTY_GOSTRING;
+struct go_string server_code=EMPTY_GOSTRING;
+struct go_string server_password=EMPTY_GOSTRING;
+struct go_string token_content=EMPTY_GOSTRING;
+struct go_string externalListenAddr=EMPTY_GOSTRING;
+struct go_string capture_output_file=EMPTY_GOSTRING;
char args_no_readline=0;
-char *pack_scripts="";
-char *pack_scripts_out="";
+struct go_string pack_scripts=EMPTY_GOSTRING;
+struct go_string pack_scripts_out=EMPTY_GOSTRING;
char enable_omega_system=0;
-char *custom_gamename="";
+struct go_string custom_gamename=EMPTY_GOSTRING;
char ingame_response=0;
extern void custom_script_engine_const(const char *key, const char *val);
extern void do_suppress_se_const(const char *key);
+// TODO: Localizations via Gettext/Glibc intl
void print_help(const char *self_name) {
printf("%s [options]\n",self_name);
printf("\t--debug: Run in debug mode.\n");
printf("\t-A , --auth-server=: Use the specified authentication server, instead of the default one.\n");
printf("\t--no-update-check: Suppress update notifications.\n");
- printf("\t-M, --no-world-chat: Ignore world chat on client side.\n");
printf("\t--force-pyrpc: Enable the PyRpcPacket interaction, client will be kicked automatically by netease's rental server.\n");
#ifdef WITH_V8
printf("\t-S, --script=<*.js>: run a .js script at start\n");
@@ -73,22 +84,6 @@ void print_help(const char *self_name) {
printf("\t\t--version-plain: Show the version of this program.\n");
}
-char *get_fb_version() {
-#ifdef FBGUI_VERSION
- return FB_VERSION "@" FBGUI_VERSION " (" FB_COMMIT ")";
-#else
- return FB_VERSION " (" FB_COMMIT ")";
-#endif
-}
-
-char *get_fb_plain_version() {
-#ifdef FBGUI_VERSION
- return FBGUI_VERSION;
-#else
- return FB_VERSION;
-#endif
-}
-
char *commit_hash() {
return FB_COMMIT_LONG;
}
@@ -118,12 +113,29 @@ void read_token(char *token_path) {
fseek(file,0,SEEK_END);
size_t flen=ftell(file);
fseek(file,0,SEEK_SET);
- token_content=malloc(flen+1);
- token_content[flen]=0;
- fread(token_content, 1, flen, file);
+ token_content.length=flen;
+ token_content.buf=malloc(flen);
+ fread(token_content.buf, 1, flen, file);
fclose(file);
}
+void quickmake(struct go_string **target_ptr) {
+ size_t length=strlen(optarg);
+ char *data=malloc(length);
+ memcpy(data, optarg, length);
+ *target_ptr=malloc(16);
+ (*target_ptr)->buf=data;
+ (*target_ptr)->length=length;
+}
+
+void quickset(struct go_string *target_ptr) {
+ size_t length=strlen(optarg);
+ char *data=malloc(length);
+ memcpy(data, optarg, length);
+ target_ptr->buf=data;
+ target_ptr->length=length;
+}
+
void quickcopy(char **target_ptr) {
size_t length=strlen(optarg)+1;
*target_ptr=malloc(length);
@@ -230,10 +242,11 @@ int _parse_args(int argc, char **argv) {
args_isDebugMode=1;
break;
case 3:
- args_disableHashCheck=1;
+ args_disableVersionCheck=1;
break;
case 5:
- args_noPyRpc=0;
+ fprintf(stderr, "--force-pyrpc not available\n");
+ return 10;
break;
case 6:
fprintf(stderr, "--no-nbt option is no longer available.\n");
@@ -274,13 +287,13 @@ int _parse_args(int argc, char **argv) {
args_no_readline=1;
break;
case 18:
- quickcopy(&pack_scripts);
+ quickset(&pack_scripts);
break;
case 19:
- quickcopy(&pack_scripts_out);
+ quickset(&pack_scripts_out);
break;
case 20:
- quickcopy(&capture_output_file);
+ quickset(&capture_output_file);
break;
case 23:
ingame_response=1;
@@ -294,38 +307,29 @@ int _parse_args(int argc, char **argv) {
print_help(argv[0]);
return 0;
case 'A':
- replaced_auth_server=1;
- quickcopy(&newAuthServer);
- break;
- case 'M':
- args_muteWorldChat=1;
+ quickset(&newAuthServer);
break;
case 'S':
#ifndef WITH_V8
fprintf(stderr,"-S, --script option isn't available: No V8 linked for this version.\n");
return 10;
#endif
- use_startup_script=1;
- quickcopy(&startup_script);
+ quickset(&startup_script);
break;
case 'c':
- specified_server=1;
- quickcopy(&server_code);
+ quickset(&server_code);
break;
case 'p':
- specified_server=1;
- quickcopy(&server_password);
+ quickset(&server_password);
break;
case 't':
- custom_token=1;
read_token(optarg);
break;
case 'T':
- custom_token=1;
- quickcopy(&token_content);
+ quickset(&token_content);
break;
case 'E':
- quickcopy(&externalListenAddr);
+ quickset(&externalListenAddr);
break;
case 'v':
print_version(1);
@@ -334,7 +338,7 @@ int _parse_args(int argc, char **argv) {
enable_omega_system=1;
break;
case 'N':
- quickcopy(&custom_gamename);
+ quickset(&custom_gamename);
break;
default:
print_help(argv[0]);
@@ -344,10 +348,74 @@ int _parse_args(int argc, char **argv) {
return -1;
}
-void parse_args(int argc, char **argv) {
+struct go_string args_var_fbversion_struct={
+ FB_VERSION " (" FB_COMMIT ")",
+ sizeof(FB_VERSION " (" FB_COMMIT ")")-1
+};
+
+/*
+// Go uses a different ABI than C, which would use BX for the 2nd return,
+// and we couldn't do that w/o asm.
+struct go_string *args_func_authServer() {
+ if(!newAuthServer) {
+ static struct go_string original_auth_server={
+ "wss://api.fastbuilder.pro:2053/",
+ 31
+ };
+ return &original_auth_server;
+ }
+ return newAuthServer;
+}*/
+
+struct go_string args_var_fbplainversion_struct={
+ FB_VERSION,
+ sizeof(FB_VERSION)-1
+};
+
+struct go_string args_fb_commit_struct={
+ FB_COMMIT,
+ sizeof(FB_COMMIT)-1
+};
+
+int args_has_specified_server() {
+ return server_code.length!=0;
+}
+
+int args_specified_token() {
+ return token_content.length!=0;
+}
+
+#ifndef WIN32
+__attribute__((constructor)) static void parse_args(int argc, char **argv) {
int ec;
if((ec=_parse_args(argc,argv))!=-1) {
exit(ec);
}
return;
}
+#else
+__attribute__((constructor)) static void parse_args_win32() {
+ int argc;
+ char **argv;
+ wchar_t **ugly_argv=CommandLineToArgvW(GetCommandLineW(), &argc);
+ argv=malloc(sizeof(char*)*argc);
+ for(int i=0;i