golang协议脚本
This commit is contained in:
parent
7a3429206e
commit
1d4baca598
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
.vs
|
.vs
|
||||||
compiler/cpp/compiler/Debug
|
compiler/cpp/compiler/Debug
|
||||||
generated
|
generated
|
||||||
|
tmp_go_check/meowmentnet/*
|
||||||
|
.vscode/*
|
||||||
37
PythonWorkSpace/IntegratedTool/Go包生成工具说明.md
Normal file
37
PythonWorkSpace/IntegratedTool/Go包生成工具说明.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Go 包生成工具
|
||||||
|
|
||||||
|
这个工具会批量读取 thrift-files/meowment-network 下的所有 thrift 文件,并生成一个统一的 Go 包目录。
|
||||||
|
|
||||||
|
默认输出位置:
|
||||||
|
|
||||||
|
- compiled_output/golang/meowmentnet
|
||||||
|
|
||||||
|
默认行为:
|
||||||
|
|
||||||
|
- 自动优先使用仓库内的 compiler/exe/thrift.exe
|
||||||
|
- 如果仓库内编译器不可用,则回退到系统 PATH 中的 thrift
|
||||||
|
- 将全部 thrift 文件生成到同一个 Go package: meowmentnet
|
||||||
|
- 启用 ignore_initialisms,保留 Id、Uid 这类字段写法,不自动改成 ID、UID
|
||||||
|
- 生成完成后自动运行 gofmt
|
||||||
|
- 使用 --module 时会自动执行 go mod tidy
|
||||||
|
|
||||||
|
直接运行:
|
||||||
|
|
||||||
|
```bat
|
||||||
|
PythonWorkSpace\IntegratedTool\启动Go包生成工具.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
常见参数:
|
||||||
|
|
||||||
|
```bat
|
||||||
|
PythonWorkSpace\IntegratedTool\启动Go包生成工具.bat --output-dir D:\temp\meowmentnet
|
||||||
|
PythonWorkSpace\IntegratedTool\启动Go包生成工具.bat --package-name netpkg
|
||||||
|
PythonWorkSpace\IntegratedTool\启动Go包生成工具.bat --module github.com/yourname/meowmentnet
|
||||||
|
PythonWorkSpace\IntegratedTool\启动Go包生成工具.bat --compiler F:\Github\thrift\thrift.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你想把生成结果直接作为一个独立 Go module 使用,建议同时传入:
|
||||||
|
|
||||||
|
```bat
|
||||||
|
PythonWorkSpace\IntegratedTool\启动Go包生成工具.bat --module github.com/yourname/meowmentnet --output-dir D:\work\meowmentnet
|
||||||
|
```
|
||||||
302
PythonWorkSpace/IntegratedTool/generate_go_package.py
Normal file
302
PythonWorkSpace/IntegratedTool/generate_go_package.py
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
"""Generate a Go package from thrift-files/meowment-network."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Iterable, Sequence
|
||||||
|
|
||||||
|
|
||||||
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||||
|
DEFAULT_SOURCE_DIR = REPO_ROOT / "thrift-files" / "meowment-network"
|
||||||
|
DEFAULT_OUTPUT_DIR = REPO_ROOT / "compiled_output" / "golang" / "meowmentnet"
|
||||||
|
DEFAULT_PACKAGE_NAME = "meowmentnet"
|
||||||
|
DEFAULT_THRIFT_IMPORT = "github.com/apache/thrift/lib/go/thrift"
|
||||||
|
|
||||||
|
|
||||||
|
class ToolError(RuntimeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args() -> argparse.Namespace:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Generate a Go package from meowment-network thrift files.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--source-dir",
|
||||||
|
type=Path,
|
||||||
|
default=DEFAULT_SOURCE_DIR,
|
||||||
|
help="Directory containing .thrift files.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--output-dir",
|
||||||
|
type=Path,
|
||||||
|
default=DEFAULT_OUTPUT_DIR,
|
||||||
|
help="Destination directory of the generated Go package.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--package-name",
|
||||||
|
default=DEFAULT_PACKAGE_NAME,
|
||||||
|
help="Generated Go package name.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--compiler",
|
||||||
|
type=Path,
|
||||||
|
help="Explicit thrift compiler executable path.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--package-prefix",
|
||||||
|
default="",
|
||||||
|
help="Optional value passed to go:package_prefix=...",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--thrift-import",
|
||||||
|
default=DEFAULT_THRIFT_IMPORT,
|
||||||
|
help="Import path of the Go thrift runtime.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--module",
|
||||||
|
default="",
|
||||||
|
help="If set, write a go.mod file with this module path.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-clean",
|
||||||
|
action="store_true",
|
||||||
|
help="Do not delete the existing output directory before copying files.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--skip-gofmt",
|
||||||
|
action="store_true",
|
||||||
|
help="Do not run gofmt after generation.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--skip-go-mod-tidy",
|
||||||
|
action="store_true",
|
||||||
|
help="Do not run go mod tidy after writing go.mod.",
|
||||||
|
)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def candidate_compilers(explicit: Path | None) -> Iterable[Path]:
|
||||||
|
seen: set[str] = set()
|
||||||
|
|
||||||
|
def emit(path: Path | None) -> Iterable[Path]:
|
||||||
|
if path is None:
|
||||||
|
return ()
|
||||||
|
resolved = str(path)
|
||||||
|
if resolved in seen:
|
||||||
|
return ()
|
||||||
|
seen.add(resolved)
|
||||||
|
return (path,)
|
||||||
|
|
||||||
|
if explicit is not None:
|
||||||
|
yield from emit(explicit)
|
||||||
|
|
||||||
|
env_compiler = Path(os.environ["THRIFT_COMPILER"]) if "THRIFT_COMPILER" in os.environ else None
|
||||||
|
yield from emit(env_compiler)
|
||||||
|
yield from emit(REPO_ROOT / "compiler" / "exe" / "thrift-go.exe")
|
||||||
|
|
||||||
|
system_compiler = shutil.which("thrift")
|
||||||
|
if system_compiler:
|
||||||
|
yield from emit(Path(system_compiler))
|
||||||
|
|
||||||
|
|
||||||
|
def probe_compiler(executable: Path) -> bool:
|
||||||
|
try:
|
||||||
|
completed = subprocess.run(
|
||||||
|
[str(executable), "-version"],
|
||||||
|
check=False,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
except OSError:
|
||||||
|
return False
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
return False
|
||||||
|
return completed.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_compiler(explicit: Path | None) -> Path:
|
||||||
|
for compiler in candidate_compilers(explicit):
|
||||||
|
if probe_compiler(compiler):
|
||||||
|
return compiler
|
||||||
|
raise ToolError(
|
||||||
|
"No working thrift compiler was found. Use --compiler or set THRIFT_COMPILER."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def find_thrift_files(source_dir: Path) -> list[Path]:
|
||||||
|
if not source_dir.exists():
|
||||||
|
raise ToolError(f"Source directory does not exist: {source_dir}")
|
||||||
|
thrift_files = sorted(source_dir.glob("*.thrift"))
|
||||||
|
if not thrift_files:
|
||||||
|
raise ToolError(f"No .thrift files were found in: {source_dir}")
|
||||||
|
return thrift_files
|
||||||
|
|
||||||
|
|
||||||
|
def build_generator_option(args: argparse.Namespace) -> str:
|
||||||
|
options = [f"package={args.package_name}"]
|
||||||
|
options.append("ignore_initialisms")
|
||||||
|
if args.package_prefix:
|
||||||
|
options.append(f"package_prefix={normalize_package_prefix(args.package_prefix)}")
|
||||||
|
if args.thrift_import:
|
||||||
|
options.append(f"thrift_import={args.thrift_import}")
|
||||||
|
options.append("skip_remote")
|
||||||
|
return "go:" + ",".join(options)
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_package_prefix(prefix: str) -> str:
|
||||||
|
normalized = prefix.strip()
|
||||||
|
if not normalized:
|
||||||
|
return normalized
|
||||||
|
return normalized if normalized.endswith("/") else normalized + "/"
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(command: Sequence[str], cwd: Path) -> None:
|
||||||
|
completed = subprocess.run(
|
||||||
|
list(command),
|
||||||
|
cwd=str(cwd),
|
||||||
|
check=False,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
if completed.returncode == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
stdout = completed.stdout.strip()
|
||||||
|
stderr = completed.stderr.strip()
|
||||||
|
details = "\n".join(part for part in (stdout, stderr) if part)
|
||||||
|
if not details:
|
||||||
|
details = "The command exited with a non-zero status and produced no output."
|
||||||
|
raise ToolError(details)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_go_sources(
|
||||||
|
compiler: Path,
|
||||||
|
source_dir: Path,
|
||||||
|
thrift_files: Sequence[Path],
|
||||||
|
package_name: str,
|
||||||
|
generator_option: str,
|
||||||
|
staging_root: Path,
|
||||||
|
) -> Path:
|
||||||
|
for thrift_file in thrift_files:
|
||||||
|
command = [
|
||||||
|
str(compiler),
|
||||||
|
"-o",
|
||||||
|
str(staging_root),
|
||||||
|
"-strict",
|
||||||
|
"--gen",
|
||||||
|
generator_option,
|
||||||
|
str(thrift_file),
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
run_command(command, cwd=source_dir)
|
||||||
|
except ToolError as exc:
|
||||||
|
raise ToolError(f"Failed to generate {thrift_file.name}:\n{exc}") from exc
|
||||||
|
|
||||||
|
package_dir = staging_root / "gen-go" / package_name
|
||||||
|
if not package_dir.exists():
|
||||||
|
raise ToolError(f"Generated package directory not found: {package_dir}")
|
||||||
|
|
||||||
|
return package_dir
|
||||||
|
|
||||||
|
|
||||||
|
def write_go_mod(output_dir: Path, module_name: str) -> None:
|
||||||
|
go_mod = output_dir / "go.mod"
|
||||||
|
go_mod.write_text(
|
||||||
|
"\n".join(
|
||||||
|
[
|
||||||
|
f"module {module_name}",
|
||||||
|
"",
|
||||||
|
"go 1.22",
|
||||||
|
"",
|
||||||
|
"require github.com/apache/thrift v0.22.0",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def copy_output(staged_package_dir: Path, output_dir: Path, clean: bool) -> None:
|
||||||
|
if clean and output_dir.exists():
|
||||||
|
shutil.rmtree(output_dir)
|
||||||
|
output_dir.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.copytree(staged_package_dir, output_dir, dirs_exist_ok=not clean)
|
||||||
|
|
||||||
|
|
||||||
|
def run_gofmt(output_dir: Path) -> None:
|
||||||
|
gofmt = shutil.which("gofmt")
|
||||||
|
if not gofmt:
|
||||||
|
print("[warn] gofmt was not found in PATH. Skipping formatting.")
|
||||||
|
return
|
||||||
|
|
||||||
|
go_files = sorted(output_dir.glob("*.go"))
|
||||||
|
if not go_files:
|
||||||
|
return
|
||||||
|
|
||||||
|
for go_file in go_files:
|
||||||
|
run_command([gofmt, "-w", str(go_file)], cwd=output_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def run_go_mod_tidy(output_dir: Path) -> None:
|
||||||
|
go = shutil.which("go")
|
||||||
|
if not go:
|
||||||
|
print("[warn] go was not found in PATH. Skipping go mod tidy.")
|
||||||
|
return
|
||||||
|
|
||||||
|
run_command([go, "mod", "tidy"], cwd=output_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_args(args: argparse.Namespace) -> None:
|
||||||
|
if not args.package_name.strip():
|
||||||
|
raise ToolError("--package-name cannot be empty.")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
args = parse_args()
|
||||||
|
try:
|
||||||
|
validate_args(args)
|
||||||
|
source_dir = args.source_dir.resolve()
|
||||||
|
output_dir = args.output_dir.resolve()
|
||||||
|
thrift_files = find_thrift_files(source_dir)
|
||||||
|
compiler = resolve_compiler(args.compiler.resolve() if args.compiler else None)
|
||||||
|
generator_option = build_generator_option(args)
|
||||||
|
with tempfile.TemporaryDirectory(prefix="thrift_go_") as tmp_dir:
|
||||||
|
staged_package_dir = generate_go_sources(
|
||||||
|
compiler=compiler,
|
||||||
|
source_dir=source_dir,
|
||||||
|
thrift_files=thrift_files,
|
||||||
|
package_name=args.package_name,
|
||||||
|
generator_option=generator_option,
|
||||||
|
staging_root=Path(tmp_dir),
|
||||||
|
)
|
||||||
|
copy_output(staged_package_dir, output_dir, clean=not args.no_clean)
|
||||||
|
if args.module:
|
||||||
|
write_go_mod(output_dir, args.module)
|
||||||
|
if not args.skip_go_mod_tidy:
|
||||||
|
run_go_mod_tidy(output_dir)
|
||||||
|
if not args.skip_gofmt:
|
||||||
|
run_gofmt(output_dir)
|
||||||
|
|
||||||
|
print(f"Compiler: {compiler}")
|
||||||
|
print(f"Source directory: {source_dir}")
|
||||||
|
print(f"Output directory: {output_dir}")
|
||||||
|
print(f"Package name: {args.package_name}")
|
||||||
|
print(f"Thrift files: {len(thrift_files)}")
|
||||||
|
if args.module:
|
||||||
|
print(f"go.mod: {args.module}")
|
||||||
|
return 0
|
||||||
|
except ToolError as exc:
|
||||||
|
print(f"[error] {exc}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
13
PythonWorkSpace/IntegratedTool/启动Go包生成工具.bat
Normal file
13
PythonWorkSpace/IntegratedTool/启动Go包生成工具.bat
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
set SCRIPT_DIR=%~dp0
|
||||||
|
set PYTHON_EXE=%SCRIPT_DIR%..\..\.venv\Scripts\python.exe
|
||||||
|
|
||||||
|
if exist "%PYTHON_EXE%" (
|
||||||
|
"%PYTHON_EXE%" "%SCRIPT_DIR%generate_go_package.py" %*
|
||||||
|
) else (
|
||||||
|
python "%SCRIPT_DIR%generate_go_package.py" %*
|
||||||
|
)
|
||||||
|
|
||||||
|
endlocal
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
// Code generated by Thrift Compiler (0.22.0). DO NOT EDIT.
|
||||||
|
|
||||||
|
package meowmentnet
|
||||||
|
|
||||||
|
var GoUnusedProtection__ int
|
||||||
33
compiled_output/golang/meowmentnet/Network-consts.go
Normal file
33
compiled_output/golang/meowmentnet/Network-consts.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Code generated by Thrift Compiler (0.22.0). DO NOT EDIT.
|
||||||
|
|
||||||
|
package meowmentnet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
thrift "github.com/apache/thrift/lib/go/thrift"
|
||||||
|
"iter"
|
||||||
|
"log/slog"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// (needed to ensure safety because of naive import list construction.)
|
||||||
|
var _ = bytes.Equal
|
||||||
|
var _ = context.Background
|
||||||
|
var _ = errors.New
|
||||||
|
var _ = fmt.Printf
|
||||||
|
var _ = iter.Pull[int]
|
||||||
|
var _ = slog.Log
|
||||||
|
var _ = time.Now
|
||||||
|
var _ = thrift.ZERO
|
||||||
|
|
||||||
|
// (needed by validator.)
|
||||||
|
var _ = strings.Contains
|
||||||
|
var _ = regexp.MatchString
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
}
|
||||||
109841
compiled_output/golang/meowmentnet/Network.go
Normal file
109841
compiled_output/golang/meowmentnet/Network.go
Normal file
File diff suppressed because it is too large
Load Diff
BIN
compiler/exe/thrift-go.exe
Normal file
BIN
compiler/exe/thrift-go.exe
Normal file
Binary file not shown.
@ -919,7 +919,7 @@ struct ReqCatReturnGiftReward {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ReqCatReturnGiftRewardGfit {
|
struct ReqCatReturnGiftRewardGift {
|
||||||
1: i32 Id,
|
1: i32 Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1544,7 +1544,7 @@ struct ReqPlayroomWork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ReqPlayroomWrokOutline {
|
struct ReqPlayroomWorkOutline {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2002,7 +2002,7 @@ struct ResCatReturnGiftReward {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ResCatReturnGiftRewardGfit {
|
struct ResCatReturnGiftRewardGift {
|
||||||
1: RES_CODE Code,
|
1: RES_CODE Code,
|
||||||
2: string Msg,
|
2: string Msg,
|
||||||
}
|
}
|
||||||
@ -2942,11 +2942,12 @@ struct ResPlayerRank {
|
|||||||
5: i32 Level,
|
5: i32 Level,
|
||||||
6: double score,
|
6: double score,
|
||||||
7: i32 type,
|
7: i32 type,
|
||||||
8: map<i32, i32> PlayroomSet
|
8: map<i32, i32> PlayroomSet,
|
||||||
9: map<i32, i32> DressSet
|
9: map<i32, i32> DressSet,
|
||||||
10: i32 FurSet,
|
10: i32 FurSet,
|
||||||
11: ActLog Last,
|
11: ActLog Last,
|
||||||
12: string PetName,
|
12: string PetName,
|
||||||
|
13: i32 Rank,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3166,7 +3167,7 @@ struct ResPlayroomWork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ResPlayroomWrokOutline {
|
struct ResPlayroomWorkOutline {
|
||||||
1: RES_CODE Code,
|
1: RES_CODE Code,
|
||||||
2: string Msg,
|
2: string Msg,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user