SDK、GDScript
介绍
GDScript SDK 适用于使用 GDScript 的 Godot 项目。
GDScript SDK 提供了与 ioGame 游戏服务器交互的简单封装,内部使用 Protobuf 数据协议通信。 配合上代码生成能避免编写大量的模板代码, 从而帮助客户端开发者减少巨大的工作量。
安装
通过 AssetLib 搜索 ooGame 并下载
点击 Install 按钮,将 sdk 安装到 addons 插件目录中。
安装后 addons 目录会多出 sdk 相关文件
SDK 设置
添加一个 my_net_config.gd 文件,用于配置 sdk 相关内容
class_name MyNetConfig
extends RefCounted
static var _socket: MyNetChannel = MyNetChannel.new()
static var current_time_millis: int = 0
static func start_net():
# --------- IoGameSetting ---------
var setting := IoGame.IoGameSetting
setting.enable_dev_mode = true
setting.set_language(IoGame.IoGameLanguage.Us)
# message callback. cn: 回调监听
setting.listen_message_callback = MyListenMessageCallback.new()
# set socket. cn: 设置网络连接
setting.net_channel = _socket
socket_init()
setting.start_net()
static func poll():
_socket.poll()
static var _heartbeat_message_bytes := IoGame.Proto.ExternalMessage.new().to_bytes()
static var _heartbeat_counter: int = 1
static func send_idle() -> void:
_heartbeat_counter += 1
#print("-------- ..HeartbeatMessage {%s}" % [_heartbeat_counter])
IoGame.IoGameSetting.net_channel.write_and_flush_byte(_heartbeat_message_bytes)
class MyListenMessageCallback extends IoGame.ListenMessageCallback:
func on_idle_callback(message: Proto.ExternalMessage):
var data_bytes := message.get_data()
var long_value := IoGame.Proto.LongValue.new()
long_value.from_bytes(data_bytes)
# Synchronize the time of each heartbeat with that of the server.
# cn: 每次心跳与服务器的时间同步
MyNetConfig.current_time_millis = long_value.get_value()
class MyNetChannel extends IoGame.SimpleNetChannel:
var _last_state: WebSocketPeer.State = WebSocketPeer.State.STATE_CLOSED
var _socket: WebSocketPeer = WebSocketPeer.new()
var _url: String = "ws://127.0.0.1:10100/websocket"
var on_open: Callable = func():
print("on_open")
var on_connecting: Callable = func():
print("on_connecting")
var on_connect_error: Callable = func(error: int):
print("on_connect_error:", error)
var on_closing: Callable = func():
print("on_closing")
var on_closed: Callable = func():
print("on_closed")
func prepare() -> void:
if _url == null or _url.is_empty():
_url = IoGame.IoGameSetting.url
var error: int = _socket.connect_to_url(_url)
if error != 0:
on_connect_error.call(error)
return
_last_state = _socket.get_ready_state()
func write_and_flush_byte(bytes: PackedByteArray) -> void:
_socket.send(bytes)
func poll() -> void:
if _socket.get_ready_state() != WebSocketPeer.State.STATE_CLOSED:
_socket.poll()
while _socket.get_available_packet_count() > 0:
var packet := _socket.get_packet()
var message := IoGame.Proto.ExternalMessage.new()
message.from_bytes(packet)
self.accept_message(message)
var state: WebSocketPeer.State = _socket.get_ready_state()
if _last_state == state:
return
_last_state = state
match state:
WebSocketPeer.State.STATE_OPEN:
on_open.call()
WebSocketPeer.State.STATE_CONNECTING:
on_connecting.call()
WebSocketPeer.State.STATE_CLOSING:
on_closing.call()
WebSocketPeer.State.STATE_CLOSED:
on_closed.call()
_:
printerr("Socket Unknown Status.")
如何生成 .proto
生成 .proto 需要使用 godobuf 库, 下面做一些简单的安装演示,更详细的安装说明可到该库上阅读 README.md 内容。
下载 godobuf 库到本地
git clone https://github.com/oniksan/godobuf.git
将 addons/protobuf 目录复制到项目的 addons 目录中。
现在,Godot 工具中目录如下

启用 godobuf 插件
现在,会多出 Godobuf tab,通过此 tab 开发者将 .proto 转换为 .gd 文件

Input protobuf file: 选择你想编译的 .proto Output GDScript file: 是 .proto 编译后的输出目录。
注意,编译后 proto 文件一定要放在 gen 目录下。
./gen/code
目录中的 action、广播、错误码
...等交互接口文件由 ioGame 生成。
代码生成可为客户端开发者减少巨大的工作量,代码使用简单,与本地方法调用一般丝滑。

处理错误码
以下分别展示了 callback、async await 两种编码风格对于错误的处理。
SdkAction 由 ioGame 生成。
func int_func():
print("-------- OnIntValue --------")
var value: int = 1
# code style: callback.
SdkAction.of_int_value(value, func(result: IoGame.ResponseResult):
result.log(result.get_int())
).on_error(func(result: IoGame.ResponseResult):
var error_code := result.get_response_status()
print("error_code: ", error_code)
print("error_info: ", result.get_error_info())
)
# code style: async await.
var _result := await SdkAction.of_await_int_value(value)
if _result.success():
_result.log(_result.get_int())
else:
var error_code := _result.get_response_status()
print("error_code: ", error_code)
print("error_info: ", _result.get_error_info())
注意事项
获取网络数据
see https://docs.godotengine.org/en/stable/tutorials/networking/websocket.html#using-websocket-in-godot
需要在 _process(_delta) 方法中调用 MyNetConfig.poll() 方法,接收网络数据
extends Node
...
func _ready():
MyNetConfig.start_net()
func _process(_delta):
# cn: 接收网络数据
# Call this in _process or _physics_process.
# Data transfer, and signals emission will only happen when calling this function.
MyNetConfig.poll()