This commit is contained in:
2025-07-04 23:41:19 +08:00
parent 7c2c32a31a
commit f0fd00d706
27 changed files with 1206 additions and 163 deletions

38
.gitignore vendored
View File

@@ -1,2 +1,40 @@
.idea
*/.idea
# Unity生成的目录
Client/unity_clone_0/
Client/unity/[Ll]ibrary/
Client/unity/[Tt]emp/
Client/unity/[Oo]bj/
Client/unity/[Bb]uild/
Client/unity/[Bb]uilds/
Client/unity/[Ll]ogs/
Client/unity/[Uu]ser[Ss]ettings/
Client/unity/[Mm]emoryCaptures/
# Unity缓存和配置文件
Client/unity/.vs/
Client/unity/.idea/
Client/unity/.vscode/
Client/unity/*.csproj
Client/unity/*.unityproj
Client/unity/*.sln
Client/unity/*.suo
Client/unity/*.tmp
Client/unity/*.user
Client/unity/*.userprefs
Client/unity/*.pidb
Client/unity/*.booproj
Client/unity/*.svd
Client/unity/*.pdb
Client/unity/*.mdb
Client/unity/*.opendb
Client/unity/*.VC.db
# Unity元数据
Client/unity/*.pidb.meta
Client/unity/*.pdb.meta
Client/unity/*.mdb.meta
# Crashlytics
Client/unity/crashlytics-build.properties

View File

@@ -3,10 +3,38 @@ package server
import (
"common/log"
"common/proto/gen/common"
"context"
"common/proto/gen/cs"
"common/proto/gen/grpc_pb"
"gateway/handler/ws_handler"
"sync"
)
func (s *Server) SendMessage(ctx context.Context, req *common.Empty) (*common.Empty, error) {
log.Infof("未实现函数")
return nil, nil
func (s *Server) ToClient(server grpc_pb.Gateway_ToClientServer) error {
wg := &sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
defer func() {
if err := recover(); err != nil {
log.Errorf("Action panic: %v", err)
}
}()
for {
if args, err := server.Recv(); err != nil {
return
} else {
if args.UID == -1 {
for _, client := range ws_handler.UserMgr.GetAll() {
client.WriteBytes(cs.MessageID(args.MessageID), args.Payload)
}
} else {
if client := ws_handler.UserMgr.GetByUID(int(args.UID)); client != nil {
client.WriteBytes(cs.MessageID(args.MessageID), args.Payload)
}
}
}
}
}()
wg.Wait()
return server.SendAndClose(&common.Empty{})
}

View File

@@ -4,6 +4,7 @@ import (
"common/discover/common"
"common/net/grpc/service"
"common/proto/gen/grpc_pb"
"gateway/handler/ws_handler"
"google.golang.org/grpc"
)
@@ -25,6 +26,7 @@ func NewServer(ttl int64) *Server {
}
func (s *Server) OnInit(serve *grpc.Server) {
ws_handler.GatewaySID = s.SID
grpc_pb.RegisterGatewayServer(serve, s)
}

View File

@@ -5,6 +5,7 @@ import (
"common/net/grpc/service"
"context"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
)
var sceneServerM map[int64]map[SceneFun]grpc.ClientStream // map[sid]map[方法名]流连接
@@ -15,7 +16,11 @@ const (
FunAction SceneFun = iota
)
func FindSceneBySID(sid int64, fun SceneFun) grpc.ClientStream {
func init() {
sceneServerM = make(map[int64]map[SceneFun]grpc.ClientStream)
}
func FindSceneBySID(sid int64, fun SceneFun) (grpc.ClientStream, error) {
g := sceneServerM[sid]
if g == nil {
g = make(map[SceneFun]grpc.ClientStream)
@@ -26,7 +31,7 @@ func FindSceneBySID(sid int64, fun SceneFun) grpc.ClientStream {
sceneClient, err := service.SceneNewClient(sid)
if err != nil {
log.Errorf("cannot find sceneClient: %v", err)
return nil
return nil, err
}
var link grpc.ClientStream
switch fun {
@@ -35,10 +40,26 @@ func FindSceneBySID(sid int64, fun SceneFun) grpc.ClientStream {
}
if err != nil {
log.Errorf("FindSceneBySID %v err: %v, sid: %v", fun, err, sid)
return nil
return nil, err
}
g[fun] = link
sceneLink = link
}
return sceneLink
return sceneLink, nil
}
func SendMessageToScene(sid int64, fun SceneFun, msg proto.Message, re ...bool) error {
stream, err := FindSceneBySID(sid, fun)
if err != nil {
return err
}
if err = stream.SendMsg(msg); err != nil {
if re == nil || !re[0] {
_ = stream.CloseSend()
delete(sceneServerM[sid], fun)
return SendMessageToScene(sid, fun, msg, true)
}
return err
}
return nil
}

View File

@@ -3,14 +3,18 @@ package ws_handler
import (
"common/log"
"common/net/socket"
"common/proto/gen/cs"
"context"
"fmt"
"go.uber.org/zap"
"google.golang.org/protobuf/proto"
"runtime/debug"
"sync"
"time"
)
var GatewaySID int64
type Client struct {
sync.WaitGroup
conn socket.ISocketConn // Socket
@@ -20,8 +24,10 @@ type Client struct {
cancel context.CancelFunc // 取消上下文
heartBeat time.Time // 最后一次心跳
UID int
SceneSID int64 // 场景服ID
UID int
SceneSID int64 // 场景服ID
InstanceID int
UniqueNo int64
}
func NewClient(uid int, conn socket.ISocketConn) *Client {
@@ -78,6 +84,39 @@ func (c *Client) OnEvent(event Event) {
}
}
func (c *Client) WriteMessage(id cs.MessageID, data proto.Message) {
d, err := proto.Marshal(data)
if err != nil {
c.logger.Errorf("WriteMessage proto.Marshal err: %v", err)
return
}
m, err := proto.Marshal(&cs.Message{
ID: id,
Payload: d,
})
if err != nil {
c.logger.Errorf("WriteMessage proto.Marshal err: %v", err)
return
}
if err = c.conn.Write(m); err != nil {
c.logger.Errorf("WriteMessage err: %v", err)
}
}
func (c *Client) WriteBytes(id cs.MessageID, data []byte) {
m, err := proto.Marshal(&cs.Message{
ID: id,
Payload: data,
})
if err != nil {
c.logger.Errorf("WriteBytes proto.Marshal err: %v", err)
return
}
if err = c.conn.Write(m); err != nil {
c.logger.Errorf("WriteBytes err: %v", err)
}
}
// CloseClient 关闭客户端同步会等待onClose执行完成
func (c *Client) CloseClient() {
if c.cancel != nil {

View File

@@ -2,25 +2,39 @@ package ws_handler
import (
"common/net/grpc/service"
"common/proto/gen/cs"
"common/proto/gen/grpc_pb"
"encoding/json"
"gateway/grpc_server/stream_client"
"google.golang.org/protobuf/proto"
"time"
)
func (c *Client) handle(event Event) {
switch e := event.(type) {
case *ClientEvent:
m, err := parseMsg(e.Msg)
if err != nil {
c.logger.Errorf("handle event json.Unmarshal err: %v", err)
msg := &cs.Message{}
if err := proto.Unmarshal(e.Msg, msg); err != nil {
c.logger.Errorf("handle event proto.Unmarshal err: %v", err)
c.cancel()
return
}
c.logger.Infof("收到客户端消息:%+v", *m)
switch m.Type {
case "enter":
c.logger.Infof("收到客户端消息:%v", msg.ID)
switch msg.ID {
case cs.MessageID_MESSAGE_ID_ENTER_INSTANCE:
m := &cs.C2S_EnterInstance{}
if err := proto.Unmarshal(msg.Payload, m); err != nil {
c.logger.Errorf("handle event proto.Unmarshal err: %v", err)
c.cancel()
return
}
c.onEnter(m)
case "action":
case cs.MessageID_MESSAGE_ID_ACTION:
m := &cs.C2S_Action{}
if err := proto.Unmarshal(msg.Payload, m); err != nil {
c.logger.Errorf("handle event proto.Unmarshal err: %v", err)
c.cancel()
return
}
c.onAction(m)
}
case *PongEvent:
@@ -28,11 +42,7 @@ func (c *Client) handle(event Event) {
}
}
func (c *Client) onEnter(msg *tempMsg) {
//_ = c.conn.Write(wapMsg(&tempMsg{
// Type: "init",
// Data: fmt.Sprintf("[%v,%v]", utils.RandInt(1, 100), utils.RandInt(1, 100)),
//}))
func (c *Client) onEnter(msg *cs.C2S_EnterInstance) {
client, err := service.SceneNewClient()
if err != nil {
c.logger.Errorf("SceneNewClient err: %v", err)
@@ -40,31 +50,34 @@ func (c *Client) onEnter(msg *tempMsg) {
}
resp, err := client.Enter(c.ctx, &grpc_pb.EnterReq{
UID: int32(c.UID),
SID: 0,
InstanceID: 1,
GatewaySID: GatewaySID,
InstanceID: msg.InstanceID,
})
if err != nil {
c.logger.Errorf("enter err: %v", err)
return
}
c.SceneSID = resp.SID
c.SceneSID = resp.SceneSID
c.UniqueNo = resp.UniqueNo
c.InstanceID = int(msg.InstanceID)
c.WriteMessage(cs.MessageID_MESSAGE_ID_POSITION, &cs.S2C_Position{
Info: []*cs.PositionInfo{{
UID: int32(c.UID),
X: 1,
Y: 1,
}},
})
}
func (c *Client) onAction(msg *tempMsg) {
func (c *Client) onAction(msg *cs.C2S_Action) {
if c.SceneSID == 0 {
return
}
d := &tempAction{}
if err := json.Unmarshal([]byte(msg.Data), d); err != nil {
return
}
m := &tempActionMove{}
if err := json.Unmarshal([]byte(d.Data), m); err != nil {
return
}
stream := stream_client.FindSceneBySID(c.SceneSID, stream_client.FunAction)
if err := stream.SendMsg(&grpc_pb.ActionReq{
Action: int32(m.Move),
if err := stream_client.SendMessageToScene(c.SceneSID, stream_client.FunAction, &grpc_pb.ActionReq{
UniqueNo: c.UniqueNo,
UID: int32(c.UID),
Action: int32(msg.Action),
Payload: msg.Payload,
}); err != nil {
c.logger.Errorf("send action err: %v", err)
}

View File

@@ -1,30 +0,0 @@
package ws_handler
import "encoding/json"
type tempMsg struct {
Type string `json:"type"`
Data string `json:"data"`
}
type tempAction struct {
Action int `json:"action"`
Data string `json:"data"`
}
type tempActionMove struct {
Move int `json:"move"`
}
func parseMsg(data []byte) (*tempMsg, error) {
m := &tempMsg{}
if err := json.Unmarshal(data, m); err != nil {
return nil, err
}
return m, nil
}
func wapMsg(m *tempMsg) []byte {
data, _ := json.Marshal(m)
return data
}

View File

@@ -30,6 +30,9 @@ func (g *GatewayWsServer) OnHandShake(conn socket.ISocketConn) {
if err != nil {
_ = conn.Close()
}
if oldClient := ws_handler.UserMgr.GetByUID(t); oldClient != nil {
oldClient.CloseClient()
}
client := ws_handler.NewClient(t, conn)
ws_handler.UserMgr.Add(t, client)
conn.SetParam("client", client)

View File

@@ -16,7 +16,7 @@ import (
var (
serverMU = sync.RWMutex{}
conn = make(map[string]*grpc_conn.GrpcConnectionMgr)
serverLeaseM = make(map[string]clientv3.LeaseID)
serverLeaseM = make(map[int64]clientv3.LeaseID)
)
func init() {
@@ -44,14 +44,14 @@ func FindServerAll(target string) map[int64]*grpc.ClientConn {
}
// RegisterGrpcServer 注册服务提供者
func RegisterGrpcServer(target, sid, addr string, ttl int64) error {
func RegisterGrpcServer(target string, sid int64, addr string, ttl int64) error {
serverMU.Lock()
defer serverMU.Unlock()
leaseID, err := common.NewLeaseAndKeepAlive(ttl)
if err != nil {
return err
}
_, err = etcd.Client().Put(context.Background(), target+"/"+sid, addr, clientv3.WithLease(leaseID))
_, err = etcd.Client().Put(context.Background(), fmt.Sprintf("%v/%v", target, sid), addr, clientv3.WithLease(leaseID))
if err != nil {
return err
}
@@ -60,7 +60,7 @@ func RegisterGrpcServer(target, sid, addr string, ttl int64) error {
}
// UnRegisterGrpcServer 解注册服务提供者
func UnRegisterGrpcServer(sid string) {
func UnRegisterGrpcServer(sid int64) {
serverMU.Lock()
defer serverMU.Unlock()
if leaseID, ok := serverLeaseM[sid]; ok {

View File

@@ -20,7 +20,7 @@ type IService interface {
type Base struct {
Target string
SID string
SID int64
Serve *grpc.Server
EtcdTTL int64
OnInit func(serve *grpc.Server)
@@ -32,7 +32,7 @@ type Base struct {
func (s *Base) Init(addr string, port int) {
s.wg = &sync.WaitGroup{}
s.wg.Add(1)
s.SID = utils.SnowflakeInstance().Generate().String()
s.SID = utils.SnowflakeInstance().Generate().Int64()
go func() {
defer s.wg.Done()
defer s.OnClose()

View File

@@ -183,7 +183,7 @@ func (w *WSConn) RemoteAddr() string {
}
func (w *WSConn) Write(data []byte) error {
return w.write(data, ws.OpText)
return w.write(data, ws.OpBinary)
}
func (w *WSConn) Ping() (err error) {

View File

@@ -3,14 +3,30 @@ syntax = "proto3";
option go_package = "common/proto/gen/cs";
import "common.proto";
enum ActionID {
ACTION_ID_INVALID = 0;
ACTION_ID_MOVE = 1; // 1-15都是移动指令
ACTION_ID_ATTACK = 16; // 攻击指令
// MESSAGE_ID_ENTER_INSTANCE
message C2S_EnterInstance {
int32 InstanceID = 1;
}
message S2C_EnterInstance {
PositionInfo Info = 1;
}
// 指令
// MESSAGE_ID_ACTION
enum ActionID {
ACTION_ID_MOVE = 0; // 0-15都是移动指令
ACTION_ID_ATTACK = 16; // 攻击指令
}
message C2S_Action {
ActionID Action = 1; // 指令ID
bytes Payload = 2; // 指令数据
}
// MESSAGE_ID_POSITION
message PositionInfo {
int32 UID = 1;
double X = 2;
double Y = 3;
}
message S2C_Position {
repeated PositionInfo Info = 1;
}

View File

@@ -5,10 +5,12 @@ import "common.proto";
enum MessageID {
MESSAGE_ID_INVALID = 0;
MESSAGE_ID_C2S_ACTION = 1; // 指令
MESSAGE_ID_ENTER_INSTANCE = 1; // 进入副本
MESSAGE_ID_ACTION = 2; // 指令
MESSAGE_ID_POSITION = 3; // 位置更新
}
message Message {
MessageID id = 1;
bytes payload = 2;
MessageID ID = 1;
bytes Payload = 2;
}

View File

@@ -0,0 +1,482 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: cs/action.proto
package cs
import (
_ "common/proto/gen/common"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// MESSAGE_ID_ACTION
type ActionID int32
const (
ActionID_ACTION_ID_MOVE ActionID = 0 // 0-15都是移动指令
ActionID_ACTION_ID_ATTACK ActionID = 16 // 攻击指令
)
// Enum value maps for ActionID.
var (
ActionID_name = map[int32]string{
0: "ACTION_ID_MOVE",
16: "ACTION_ID_ATTACK",
}
ActionID_value = map[string]int32{
"ACTION_ID_MOVE": 0,
"ACTION_ID_ATTACK": 16,
}
)
func (x ActionID) Enum() *ActionID {
p := new(ActionID)
*p = x
return p
}
func (x ActionID) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ActionID) Descriptor() protoreflect.EnumDescriptor {
return file_cs_action_proto_enumTypes[0].Descriptor()
}
func (ActionID) Type() protoreflect.EnumType {
return &file_cs_action_proto_enumTypes[0]
}
func (x ActionID) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ActionID.Descriptor instead.
func (ActionID) EnumDescriptor() ([]byte, []int) {
return file_cs_action_proto_rawDescGZIP(), []int{0}
}
// MESSAGE_ID_ENTER_INSTANCE
type C2S_EnterInstance struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
InstanceID int32 `protobuf:"varint,1,opt,name=InstanceID,proto3" json:"InstanceID,omitempty"`
}
func (x *C2S_EnterInstance) Reset() {
*x = C2S_EnterInstance{}
if protoimpl.UnsafeEnabled {
mi := &file_cs_action_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *C2S_EnterInstance) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*C2S_EnterInstance) ProtoMessage() {}
func (x *C2S_EnterInstance) ProtoReflect() protoreflect.Message {
mi := &file_cs_action_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use C2S_EnterInstance.ProtoReflect.Descriptor instead.
func (*C2S_EnterInstance) Descriptor() ([]byte, []int) {
return file_cs_action_proto_rawDescGZIP(), []int{0}
}
func (x *C2S_EnterInstance) GetInstanceID() int32 {
if x != nil {
return x.InstanceID
}
return 0
}
type S2C_EnterInstance struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Info *PositionInfo `protobuf:"bytes,1,opt,name=Info,proto3" json:"Info,omitempty"`
}
func (x *S2C_EnterInstance) Reset() {
*x = S2C_EnterInstance{}
if protoimpl.UnsafeEnabled {
mi := &file_cs_action_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *S2C_EnterInstance) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*S2C_EnterInstance) ProtoMessage() {}
func (x *S2C_EnterInstance) ProtoReflect() protoreflect.Message {
mi := &file_cs_action_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use S2C_EnterInstance.ProtoReflect.Descriptor instead.
func (*S2C_EnterInstance) Descriptor() ([]byte, []int) {
return file_cs_action_proto_rawDescGZIP(), []int{1}
}
func (x *S2C_EnterInstance) GetInfo() *PositionInfo {
if x != nil {
return x.Info
}
return nil
}
type C2S_Action struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Action ActionID `protobuf:"varint,1,opt,name=Action,proto3,enum=ActionID" json:"Action,omitempty"` // 指令ID
Payload []byte `protobuf:"bytes,2,opt,name=Payload,proto3" json:"Payload,omitempty"` // 指令数据
}
func (x *C2S_Action) Reset() {
*x = C2S_Action{}
if protoimpl.UnsafeEnabled {
mi := &file_cs_action_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *C2S_Action) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*C2S_Action) ProtoMessage() {}
func (x *C2S_Action) ProtoReflect() protoreflect.Message {
mi := &file_cs_action_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use C2S_Action.ProtoReflect.Descriptor instead.
func (*C2S_Action) Descriptor() ([]byte, []int) {
return file_cs_action_proto_rawDescGZIP(), []int{2}
}
func (x *C2S_Action) GetAction() ActionID {
if x != nil {
return x.Action
}
return ActionID_ACTION_ID_MOVE
}
func (x *C2S_Action) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
// MESSAGE_ID_POSITION
type PositionInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
UID int32 `protobuf:"varint,1,opt,name=UID,proto3" json:"UID,omitempty"`
X float64 `protobuf:"fixed64,2,opt,name=X,proto3" json:"X,omitempty"`
Y float64 `protobuf:"fixed64,3,opt,name=Y,proto3" json:"Y,omitempty"`
}
func (x *PositionInfo) Reset() {
*x = PositionInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_cs_action_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PositionInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PositionInfo) ProtoMessage() {}
func (x *PositionInfo) ProtoReflect() protoreflect.Message {
mi := &file_cs_action_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PositionInfo.ProtoReflect.Descriptor instead.
func (*PositionInfo) Descriptor() ([]byte, []int) {
return file_cs_action_proto_rawDescGZIP(), []int{3}
}
func (x *PositionInfo) GetUID() int32 {
if x != nil {
return x.UID
}
return 0
}
func (x *PositionInfo) GetX() float64 {
if x != nil {
return x.X
}
return 0
}
func (x *PositionInfo) GetY() float64 {
if x != nil {
return x.Y
}
return 0
}
type S2C_Position struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Info []*PositionInfo `protobuf:"bytes,1,rep,name=Info,proto3" json:"Info,omitempty"`
}
func (x *S2C_Position) Reset() {
*x = S2C_Position{}
if protoimpl.UnsafeEnabled {
mi := &file_cs_action_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *S2C_Position) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*S2C_Position) ProtoMessage() {}
func (x *S2C_Position) ProtoReflect() protoreflect.Message {
mi := &file_cs_action_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use S2C_Position.ProtoReflect.Descriptor instead.
func (*S2C_Position) Descriptor() ([]byte, []int) {
return file_cs_action_proto_rawDescGZIP(), []int{4}
}
func (x *S2C_Position) GetInfo() []*PositionInfo {
if x != nil {
return x.Info
}
return nil
}
var File_cs_action_proto protoreflect.FileDescriptor
var file_cs_action_proto_rawDesc = []byte{
0x0a, 0x0f, 0x63, 0x73, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x33, 0x0a, 0x11, 0x43, 0x32, 0x53, 0x5f, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e,
0x63, 0x65, 0x49, 0x44, 0x22, 0x36, 0x0a, 0x11, 0x53, 0x32, 0x43, 0x5f, 0x45, 0x6e, 0x74, 0x65,
0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x49, 0x6e, 0x66,
0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x49, 0x0a, 0x0a,
0x43, 0x32, 0x53, 0x5f, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x06, 0x41, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x41, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x49, 0x44, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a,
0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07,
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x3c, 0x0a, 0x0c, 0x50, 0x6f, 0x73, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x01,
0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x0c, 0x0a, 0x01, 0x58, 0x18, 0x02,
0x20, 0x01, 0x28, 0x01, 0x52, 0x01, 0x58, 0x12, 0x0c, 0x0a, 0x01, 0x59, 0x18, 0x03, 0x20, 0x01,
0x28, 0x01, 0x52, 0x01, 0x59, 0x22, 0x31, 0x0a, 0x0c, 0x53, 0x32, 0x43, 0x5f, 0x50, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x2a, 0x34, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49,
0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x43, 0x54, 0x49,
0x4f, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x10, 0x10, 0x42, 0x15,
0x5a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67,
0x65, 0x6e, 0x2f, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_cs_action_proto_rawDescOnce sync.Once
file_cs_action_proto_rawDescData = file_cs_action_proto_rawDesc
)
func file_cs_action_proto_rawDescGZIP() []byte {
file_cs_action_proto_rawDescOnce.Do(func() {
file_cs_action_proto_rawDescData = protoimpl.X.CompressGZIP(file_cs_action_proto_rawDescData)
})
return file_cs_action_proto_rawDescData
}
var file_cs_action_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_cs_action_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_cs_action_proto_goTypes = []interface{}{
(ActionID)(0), // 0: ActionID
(*C2S_EnterInstance)(nil), // 1: C2S_EnterInstance
(*S2C_EnterInstance)(nil), // 2: S2C_EnterInstance
(*C2S_Action)(nil), // 3: C2S_Action
(*PositionInfo)(nil), // 4: PositionInfo
(*S2C_Position)(nil), // 5: S2C_Position
}
var file_cs_action_proto_depIdxs = []int32{
4, // 0: S2C_EnterInstance.Info:type_name -> PositionInfo
0, // 1: C2S_Action.Action:type_name -> ActionID
4, // 2: S2C_Position.Info:type_name -> PositionInfo
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_cs_action_proto_init() }
func file_cs_action_proto_init() {
if File_cs_action_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_cs_action_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*C2S_EnterInstance); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_cs_action_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*S2C_EnterInstance); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_cs_action_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*C2S_Action); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_cs_action_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PositionInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_cs_action_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*S2C_Position); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cs_action_proto_rawDesc,
NumEnums: 1,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_cs_action_proto_goTypes,
DependencyIndexes: file_cs_action_proto_depIdxs,
EnumInfos: file_cs_action_proto_enumTypes,
MessageInfos: file_cs_action_proto_msgTypes,
}.Build()
File_cs_action_proto = out.File
file_cs_action_proto_rawDesc = nil
file_cs_action_proto_goTypes = nil
file_cs_action_proto_depIdxs = nil
}

View File

@@ -0,0 +1,217 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.1
// source: cs/define.proto
package cs
import (
_ "common/proto/gen/common"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type MessageID int32
const (
MessageID_MESSAGE_ID_INVALID MessageID = 0
MessageID_MESSAGE_ID_ENTER_INSTANCE MessageID = 1 // 进入副本
MessageID_MESSAGE_ID_ACTION MessageID = 2 // 指令
MessageID_MESSAGE_ID_POSITION MessageID = 3 // 位置更新
)
// Enum value maps for MessageID.
var (
MessageID_name = map[int32]string{
0: "MESSAGE_ID_INVALID",
1: "MESSAGE_ID_ENTER_INSTANCE",
2: "MESSAGE_ID_ACTION",
3: "MESSAGE_ID_POSITION",
}
MessageID_value = map[string]int32{
"MESSAGE_ID_INVALID": 0,
"MESSAGE_ID_ENTER_INSTANCE": 1,
"MESSAGE_ID_ACTION": 2,
"MESSAGE_ID_POSITION": 3,
}
)
func (x MessageID) Enum() *MessageID {
p := new(MessageID)
*p = x
return p
}
func (x MessageID) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (MessageID) Descriptor() protoreflect.EnumDescriptor {
return file_cs_define_proto_enumTypes[0].Descriptor()
}
func (MessageID) Type() protoreflect.EnumType {
return &file_cs_define_proto_enumTypes[0]
}
func (x MessageID) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use MessageID.Descriptor instead.
func (MessageID) EnumDescriptor() ([]byte, []int) {
return file_cs_define_proto_rawDescGZIP(), []int{0}
}
type Message struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ID MessageID `protobuf:"varint,1,opt,name=ID,proto3,enum=MessageID" json:"ID,omitempty"`
Payload []byte `protobuf:"bytes,2,opt,name=Payload,proto3" json:"Payload,omitempty"`
}
func (x *Message) Reset() {
*x = Message{}
if protoimpl.UnsafeEnabled {
mi := &file_cs_define_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Message) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Message) ProtoMessage() {}
func (x *Message) ProtoReflect() protoreflect.Message {
mi := &file_cs_define_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Message.ProtoReflect.Descriptor instead.
func (*Message) Descriptor() ([]byte, []int) {
return file_cs_define_proto_rawDescGZIP(), []int{0}
}
func (x *Message) GetID() MessageID {
if x != nil {
return x.ID
}
return MessageID_MESSAGE_ID_INVALID
}
func (x *Message) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
var File_cs_define_proto protoreflect.FileDescriptor
var file_cs_define_proto_rawDesc = []byte{
0x0a, 0x0f, 0x63, 0x73, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x3f, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x02, 0x49, 0x44,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x49, 0x44, 0x52, 0x02, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x2a, 0x72, 0x0a, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44, 0x12, 0x16, 0x0a,
0x12, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x41,
0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45,
0x5f, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e,
0x43, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f,
0x49, 0x44, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x4d,
0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x49, 0x44, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49,
0x4f, 0x4e, 0x10, 0x03, 0x42, 0x15, 0x5a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (
file_cs_define_proto_rawDescOnce sync.Once
file_cs_define_proto_rawDescData = file_cs_define_proto_rawDesc
)
func file_cs_define_proto_rawDescGZIP() []byte {
file_cs_define_proto_rawDescOnce.Do(func() {
file_cs_define_proto_rawDescData = protoimpl.X.CompressGZIP(file_cs_define_proto_rawDescData)
})
return file_cs_define_proto_rawDescData
}
var file_cs_define_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_cs_define_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_cs_define_proto_goTypes = []interface{}{
(MessageID)(0), // 0: MessageID
(*Message)(nil), // 1: Message
}
var file_cs_define_proto_depIdxs = []int32{
0, // 0: Message.ID:type_name -> MessageID
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_cs_define_proto_init() }
func file_cs_define_proto_init() {
if File_cs_define_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_cs_define_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Message); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cs_define_proto_rawDesc,
NumEnums: 1,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_cs_define_proto_goTypes,
DependencyIndexes: file_cs_define_proto_depIdxs,
EnumInfos: file_cs_define_proto_enumTypes,
MessageInfos: file_cs_define_proto_msgTypes,
}.Build()
File_cs_define_proto = out.File
file_cs_define_proto_rawDesc = nil
file_cs_define_proto_goTypes = nil
file_cs_define_proto_depIdxs = nil
}

View File

@@ -26,8 +26,9 @@ type ToClientReq struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
UID int32 `protobuf:"varint,1,opt,name=UID,proto3" json:"UID,omitempty"`
Payload []byte `protobuf:"bytes,2,opt,name=Payload,proto3" json:"Payload,omitempty"`
UID int32 `protobuf:"varint,1,opt,name=UID,proto3" json:"UID,omitempty"`
MessageID int32 `protobuf:"varint,2,opt,name=MessageID,proto3" json:"MessageID,omitempty"`
Payload []byte `protobuf:"bytes,3,opt,name=Payload,proto3" json:"Payload,omitempty"`
}
func (x *ToClientReq) Reset() {
@@ -69,6 +70,13 @@ func (x *ToClientReq) GetUID() int32 {
return 0
}
func (x *ToClientReq) GetMessageID() int32 {
if x != nil {
return x.MessageID
}
return 0
}
func (x *ToClientReq) GetPayload() []byte {
if x != nil {
return x.Payload
@@ -81,16 +89,17 @@ var File_grpc_gateway_proto protoreflect.FileDescriptor
var file_grpc_gateway_proto_rawDesc = []byte{
0x0a, 0x12, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0x39, 0x0a, 0x0b, 0x54, 0x6f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65,
0x74, 0x6f, 0x22, 0x57, 0x0a, 0x0b, 0x54, 0x6f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65,
0x71, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03,
0x55, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0x2f, 0x0a,
0x07, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x08, 0x54, 0x6f, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x12, 0x0c, 0x2e, 0x54, 0x6f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52,
0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x42, 0x1a,
0x5a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67,
0x65, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x55, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44,
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49,
0x44, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0x2f, 0x0a, 0x07, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x08, 0x54, 0x6f, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x12, 0x0c, 0x2e, 0x54, 0x6f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71,
0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x42, 0x1a, 0x5a, 0x18,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e,
0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -27,7 +27,7 @@ type EnterReq struct {
unknownFields protoimpl.UnknownFields
UID int32 `protobuf:"varint,1,opt,name=UID,proto3" json:"UID,omitempty"` // 用户ID
SID int64 `protobuf:"varint,2,opt,name=SID,proto3" json:"SID,omitempty"` // 服务ID
GatewaySID int64 `protobuf:"varint,2,opt,name=GatewaySID,proto3" json:"GatewaySID,omitempty"` // 网关服务ID
InstanceID int32 `protobuf:"varint,3,opt,name=InstanceID,proto3" json:"InstanceID,omitempty"` // 副本ID
}
@@ -70,9 +70,9 @@ func (x *EnterReq) GetUID() int32 {
return 0
}
func (x *EnterReq) GetSID() int64 {
func (x *EnterReq) GetGatewaySID() int64 {
if x != nil {
return x.SID
return x.GatewaySID
}
return 0
}
@@ -89,7 +89,7 @@ type EnterResp struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SID int64 `protobuf:"varint,1,opt,name=SID,proto3" json:"SID,omitempty"` // 服务ID
SceneSID int64 `protobuf:"varint,1,opt,name=SceneSID,proto3" json:"SceneSID,omitempty"` // 场景服务ID
UniqueNo int64 `protobuf:"varint,2,opt,name=UniqueNo,proto3" json:"UniqueNo,omitempty"` // 副本唯一编号
}
@@ -125,9 +125,9 @@ func (*EnterResp) Descriptor() ([]byte, []int) {
return file_grpc_scene_proto_rawDescGZIP(), []int{1}
}
func (x *EnterResp) GetSID() int64 {
func (x *EnterResp) GetSceneSID() int64 {
if x != nil {
return x.SID
return x.SceneSID
}
return 0
}
@@ -215,29 +215,31 @@ var File_grpc_scene_proto protoreflect.FileDescriptor
var file_grpc_scene_proto_rawDesc = []byte{
0x0a, 0x10, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x22, 0x4e, 0x0a, 0x08, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03,
0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x10,
0x0a, 0x03, 0x53, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x53, 0x49, 0x44,
0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x18, 0x03,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44,
0x22, 0x39, 0x0a, 0x09, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a,
0x03, 0x53, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x53, 0x49, 0x44, 0x12,
0x1a, 0x0a, 0x08, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x08, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4e, 0x6f, 0x22, 0x6b, 0x0a, 0x09, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x6e, 0x69, 0x71,
0x75, 0x65, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x55, 0x6e, 0x69, 0x71,
0x75, 0x65, 0x4e, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18,
0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0x4b, 0x0a, 0x05, 0x53, 0x63, 0x65, 0x6e,
0x65, 0x12, 0x20, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x09, 0x2e, 0x45, 0x6e, 0x74,
0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73,
0x70, 0x22, 0x00, 0x12, 0x20, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x2e,
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x22, 0x00, 0x28, 0x01, 0x42, 0x1a, 0x5a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x70,
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x22, 0x5c, 0x0a, 0x08, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03,
0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x1e,
0x0a, 0x0a, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0a, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x49, 0x44, 0x12, 0x1e,
0x0a, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, 0x22, 0x43,
0x0a, 0x09, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x53,
0x63, 0x65, 0x6e, 0x65, 0x53, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x53,
0x63, 0x65, 0x6e, 0x65, 0x53, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55, 0x6e, 0x69, 0x71, 0x75,
0x65, 0x4e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x55, 0x6e, 0x69, 0x71, 0x75,
0x65, 0x4e, 0x6f, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x12, 0x1a, 0x0a, 0x08, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x08, 0x55, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4e, 0x6f, 0x12, 0x10, 0x0a, 0x03,
0x55, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x55, 0x49, 0x44, 0x12, 0x16,
0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06,
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x32, 0x4b, 0x0a, 0x05, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x45, 0x6e, 0x74,
0x65, 0x72, 0x12, 0x09, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e,
0x45, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x20, 0x0a, 0x06, 0x41,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x71, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x42, 0x1a, 0x5a,
0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65,
0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (

View File

@@ -9,6 +9,7 @@ service Gateway {
message ToClientReq {
int32 UID = 1;
bytes Payload = 2;
int32 MessageID = 2;
bytes Payload = 3;
}

View File

@@ -10,12 +10,12 @@ service Scene {
message EnterReq {
int32 UID = 1; // 用户ID
int64 SID = 2; // 服务ID
int64 GatewaySID = 2; // 网关服务ID
int32 InstanceID = 3; // 副本ID
}
message EnterResp {
int64 SID = 1; // 服务ID
int64 SceneSID = 1; // 场景服务ID
int64 UniqueNo = 2; // 副本唯一编号
}

View File

@@ -9,7 +9,7 @@ import (
"github.com/judwhite/go-svc"
"runtime/debug"
"scene/config"
"scene/grpc_server"
"scene/grpc_server/server"
"sync"
)
@@ -41,7 +41,7 @@ func (p *Program) Start() error {
}()
discover.Listen()
p.server = grpc_server.NewServer(config.Get().Serve.Grpc.TTL)
p.server = server.NewServer(config.Get().Serve.Grpc.TTL)
p.server.Init(config.Get().Serve.Grpc.Address, config.Get().Serve.Grpc.Port)
return nil

View File

@@ -1,19 +1,30 @@
package grpc_server
package server
import (
"common/log"
"common/proto/gen/common"
"common/proto/gen/grpc_pb"
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"scene/instance"
"sync"
)
func (s *Server) Enter(ctx context.Context, req *grpc_pb.EnterReq) (*grpc_pb.EnterResp, error) {
log.Infof("enter 触发 %v", req.SID)
return nil, status.Errorf(codes.Unimplemented, "")
var i *instance.Instance
if len(instance.Mgr.GetAll()) == 0 {
i = instance.NewScene(s.SID, int(req.InstanceID))
i.Start(s.EtcdTTL)
} else {
for _, v := range instance.Mgr.GetAll() {
i = v
break
}
}
i.EventIn <- req
return &grpc_pb.EnterResp{
SceneSID: s.SID,
UniqueNo: i.UniqueNo,
}, nil
}
func (s *Server) Action(server grpc_pb.Scene_ActionServer) error {

View File

@@ -1,4 +1,4 @@
package grpc_server
package server
import (
"common/discover/common"

View File

@@ -0,0 +1,65 @@
package stream_client
import (
"common/log"
"common/net/grpc/service"
"context"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
)
var gatewayServerM map[int64]map[GatewayFun]grpc.ClientStream // map[sid]map[方法名]流连接
type GatewayFun int
const (
FunToClient GatewayFun = iota
)
func init() {
gatewayServerM = make(map[int64]map[GatewayFun]grpc.ClientStream)
}
func FindGatewayBySID(sid int64, fun GatewayFun) (grpc.ClientStream, error) {
g := gatewayServerM[sid]
if g == nil {
g = make(map[GatewayFun]grpc.ClientStream)
gatewayServerM[sid] = g
}
gatewayLink := g[fun]
if gatewayLink == nil {
gatewayClient, err := service.GatewayNewClient(sid)
if err != nil {
log.Errorf("cannot find gatewayClient: %v", err)
return nil, err
}
var link grpc.ClientStream
switch fun {
case FunToClient:
link, err = gatewayClient.ToClient(context.Background())
}
if err != nil {
log.Errorf("FindGatewayBySID %v err: %v, sid: %v", fun, err, sid)
return nil, err
}
g[fun] = link
gatewayLink = link
}
return gatewayLink, nil
}
func SendMessageToGateway(sid int64, fun GatewayFun, msg proto.Message, re ...bool) error {
stream, err := FindGatewayBySID(sid, fun)
if err != nil {
return err
}
if err = stream.SendMsg(msg); err != nil {
if re == nil || !re[0] {
_ = stream.CloseSend()
delete(gatewayServerM[sid], fun)
return SendMessageToGateway(sid, fun, msg, true)
}
return err
}
return nil
}

View File

@@ -1,9 +0,0 @@
package instance
import "google.golang.org/protobuf/proto"
type Msg2Client struct {
SID string
UID int
Msg proto.Message
}

View File

@@ -3,11 +3,16 @@ package instance
import (
"common/discover"
"common/log"
"common/proto/gen/cs"
"common/proto/gen/grpc_pb"
"common/utils"
"context"
"fmt"
"go.uber.org/zap"
"google.golang.org/protobuf/proto"
"runtime/debug"
"scene/grpc_server/stream_client"
"scene/npc"
"sync"
"time"
)
@@ -15,27 +20,27 @@ import (
// Instance 场景类
type Instance struct {
wg sync.WaitGroup
players map[int]*PlayerNode // 存储所有玩家节点 [uid]
ctx context.Context // 停止指令
cancel context.CancelFunc // 停止函数
players map[int]*npc.PlayerNode // 存储所有玩家节点 [uid]
ctx context.Context // 停止指令
cancel context.CancelFunc // 停止函数
logger *zap.SugaredLogger // 日志
SID int64 // 服务ID
InstanceID int // 副本ID
UniqueNo int64 // 唯一编号
EventIn chan proto.Message // 消息入口
EventOut chan *Msg2Client // 消息出口
}
// NewScene 初始化场景
func NewScene(sid int64, instanceID int) *Instance {
s := &Instance{
players: make(map[int]*PlayerNode),
players: make(map[int]*npc.PlayerNode),
SID: sid,
InstanceID: instanceID,
UniqueNo: utils.SnowflakeInstance().Generate().Int64(),
EventIn: make(chan proto.Message),
EventOut: make(chan *Msg2Client),
}
s.logger = log.GetLogger().Named(fmt.Sprintf("%v:%v", s.InstanceID, s.UniqueNo))
s.ctx, s.cancel = context.WithCancel(context.Background())
return s
}
@@ -46,20 +51,20 @@ func (i *Instance) Start(ttl int64) {
defer i.wg.Done()
defer func() {
if err := recover(); err != nil {
log.Infof("instance err: %v, uniqueNo: %v", err, i.UniqueNo)
i.logger.Infof("instance err: %v", err)
debug.PrintStack()
}
}()
Mgr.Add(i.UniqueNo, i)
defer func() {
log.Infof("instance destroy: %v, %v", i.InstanceID, i.UniqueNo)
i.logger.Infof("instance destroy")
discover.UnRegisterInstance(i.UniqueNo)
close(i.EventIn)
Mgr.Delete(i.UniqueNo)
}()
if err := discover.RegisterInstance(i.SID, i.InstanceID, i.UniqueNo, ttl); err != nil {
log.Errorf("register discover error")
i.logger.Errorf("register discover error")
return
}
// 场景心跳
@@ -75,23 +80,46 @@ func (i *Instance) Start(ttl int64) {
}
}
}()
log.Infof("new scene start: %v, %v", i.InstanceID, i.UniqueNo)
i.logger.Infof("new scene start")
}
// 网络帧
func (i *Instance) onEvent(e proto.Message) {
switch v := e.(type) {
case *grpc_pb.EnterReq:
i.players[int(v.UID)] = npc.NewPlayerNode(v.GatewaySID, int(v.UID))
case *grpc_pb.ActionReq:
if node, ok := i.players[int(v.UID)]; ok {
node.addAction(v)
node.AddAction(v)
}
}
}
// 逻辑帧
func (i *Instance) onLogic() {
positionUpdate := make([]*cs.PositionInfo, 0)
sid := int64(0)
// 优先处理移动指令
for _, node := range i.players {
node.logicMove()
if node.LogicMove() {
positionUpdate = append(positionUpdate, &cs.PositionInfo{
UID: int32(node.UID),
X: node.Position[0],
Y: node.Position[1],
})
sid = node.GatewaySID
}
}
if len(positionUpdate) > 0 {
payload, _ := proto.Marshal(&cs.S2C_Position{
Info: positionUpdate,
})
if err := stream_client.SendMessageToGateway(sid, stream_client.FunToClient, &grpc_pb.ToClientReq{
UID: -1,
MessageID: int32(cs.MessageID_MESSAGE_ID_POSITION),
Payload: payload,
}); err != nil {
i.logger.Errorf("send action err: %v", err)
}
}
}

76
Server/scene/npc/npc.go Normal file
View File

@@ -0,0 +1,76 @@
package npc
import (
"common/proto/gen/grpc_pb"
)
// NPCNode 定义NPC节点
type NPCNode struct {
UID int // 用户ID
GatewaySID int64 // 网关服务ID
Position [2]float64 // 二维坐标 [x, y]
MoveCross int8 // 移动十字1 上 2 下 4 左 8 右
Action []*grpc_pb.ActionReq // 其他操作
}
func NewNPCNode(gatewaySID int64, uid int) *NPCNode {
return &NPCNode{
UID: uid,
GatewaySID: gatewaySID,
Position: [2]float64{0, 0},
MoveCross: 0,
Action: make([]*grpc_pb.ActionReq, 0),
}
}
// 逻辑帧-移动
func (p *NPCNode) logicMove() bool {
if p.MoveCross&DirUp != 0 && p.MoveCross&DirDown != 0 {
p.MoveCross &^= DirUp | DirDown
}
if p.MoveCross&DirLeft != 0 && p.MoveCross&DirRight != 0 {
p.MoveCross &^= DirLeft | DirRight
}
var moveX, moveY float64
if p.MoveCross&DirUp != 0 {
moveY += 1
}
if p.MoveCross&DirDown != 0 {
moveY -= 1
}
if p.MoveCross&DirLeft != 0 {
moveX -= 1
}
if p.MoveCross&DirRight != 0 {
moveX += 1
}
// 没有移动
if moveX == 0 && moveY == 0 {
return false
}
if moveX != 0 && moveY != 0 {
const diagonalFactor = 0.7071
moveX *= diagonalFactor
moveY *= diagonalFactor
}
speed := 10.0
p.Position[0] += moveX * speed
p.Position[1] += moveY * speed
if p.Position[0] < 0 {
p.Position[0] = 0
}
if p.Position[0] > 400 {
p.Position[0] = 400
}
if p.Position[1] < 0 {
p.Position[1] = 0
}
if p.Position[1] > 400 {
p.Position[1] = 400
}
return true
}

View File

@@ -1,4 +1,4 @@
package instance
package npc
import (
"common/proto/gen/grpc_pb"
@@ -6,14 +6,26 @@ import (
// PlayerNode 定义玩家节点结构体
type PlayerNode struct {
ID int
UID int // 用户ID
GatewaySID int64 // 网关服务ID
Position [2]float64 // 二维坐标 [x, y]
MoveCross int8 // 移动十字1 上 2 下 4 左 8 右
Action []*grpc_pb.ActionReq // 其他操作
}
// 将指令存储到玩家身上
func (p *PlayerNode) addAction(e *grpc_pb.ActionReq) {
func NewPlayerNode(gatewaySID int64, uid int) *PlayerNode {
return &PlayerNode{
UID: uid,
GatewaySID: gatewaySID,
Position: [2]float64{0, 0},
MoveCross: 0,
Action: make([]*grpc_pb.ActionReq, 0),
}
}
// AddAction 将指令存储到玩家身上
func (p *PlayerNode) AddAction(e *grpc_pb.ActionReq) {
if e.Action < 16 {
p.MoveCross = int8(e.Action)
} else {
@@ -28,8 +40,8 @@ const (
DirRight // 8 (00001000)
)
// 逻辑帧-移动
func (p *PlayerNode) logicMove() {
// LogicMove 逻辑帧-移动
func (p *PlayerNode) LogicMove() bool {
if p.MoveCross&DirUp != 0 && p.MoveCross&DirDown != 0 {
p.MoveCross &^= DirUp | DirDown
}
@@ -50,6 +62,10 @@ func (p *PlayerNode) logicMove() {
if p.MoveCross&DirRight != 0 {
moveX += 1
}
// 没有移动
if moveX == 0 && moveY == 0 {
return false
}
if moveX != 0 && moveY != 0 {
const diagonalFactor = 0.7071
@@ -57,7 +73,20 @@ func (p *PlayerNode) logicMove() {
moveY *= diagonalFactor
}
speed := 100.0
speed := 10.0
p.Position[0] += moveX * speed
p.Position[1] += moveY * speed
if p.Position[0] < 0 {
p.Position[0] = 0
}
if p.Position[0] > 400 {
p.Position[0] = 400
}
if p.Position[1] < 0 {
p.Position[1] = 0
}
if p.Position[1] > 400 {
p.Position[1] = 400
}
return true
}