分享
  1. 首页
  2. 文章

LollipopGo开源游戏服务器框架--global服务器源码

Golang语言社区 · · 2861 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

大家好,我是彬哥,本节给大家讲下LollipopGov1.0.20190102版本游戏服务器globla服务器,抛砖引玉了,主要是针对Go语言游戏服务器Global服务器处理。

package main
import (
 "LollipopGo/LollipopGo/conf"
 "LollipopGo/LollipopGo/error"
 "LollipopGo/LollipopGo/log"
 "LollipopGo/LollipopGo/match"
 "Proto"
 "Proto/Proto2"
 "flag"
 "fmt"
 "net/rpc"
 "net/rpc/jsonrpc"
 "strings"
 "time"
 "LollipopGo/LollipopGo/util"
 "LollipopGo/ReadCSV"
 "LollipopGo/LollipopGo/player"
 "code.google.com/p/go.net/websocket"
)
/*
 匹配、活动服务器
 1 匹配玩家活动
*/
var addrG = flag.String("addrG", "127.0.0.1:8888", "http service address")
var Conn *websocket.Conn
var ConnRPC *rpc.Client
func init() {
 if !initGateWayNet() {
 fmt.Println("链接 gateway server 失败!")
 return
 }
 fmt.Println("链接 gateway server 成功!")
 initNetRPC()
 return
}
func initNetRPC() {
 client, err := jsonrpc.Dial("tcp", service)
 if err != nil {
 log.Debug("dial error:", err)
 //panic("dial RPC Servre error")
 return
 }
 ConnRPC = client
}
func initGateWayNet() bool {
 fmt.Println("用户客户端客户端模拟!")
 url := "ws://" + *addrG + "/GolangLtd"
 conn, err := websocket.Dial(url, "", "test://golang/")
 if err != nil {
 fmt.Println("err:", err.Error())
 return false
 }
 Conn = conn
 go GameServerReceiveG(Conn)
 initConn(Conn)
 return true
}
// 处理数据
func GameServerReceiveG(ws *websocket.Conn) {
 for {
 var content string
 err := websocket.Message.Receive(ws, &content)
 if err != nil {
 fmt.Println(err.Error())
 continue
 }
 fmt.Println(strings.Trim("", "\""))
 fmt.Println(content)
 content = strings.Replace(content, "\"", "", -1)
 contentstr, errr := base64Decode([]byte(content))
 if errr != nil {
 fmt.Println(errr)
 continue
 }
 go SyncMeassgeFunG(string(contentstr))
 }
}
// 链接分发 处理
func SyncMeassgeFunG(content string) {
 var r Requestbody
 r.req = content
 if ProtocolData, err := r.Json2map(); err == nil {
 HandleCltProtocolG(ProtocolData["Protocol"], ProtocolData["Protocol2"], ProtocolData)
 } else {
 log.Debug("解析失败:", err.Error())
 }
}
// 主协议处理
func HandleCltProtocolG(protocol interface{}, protocol2 interface{}, ProtocolData map[string]interface{}) {
 // defer func() { // 必须要先声明defer,否则不能捕获到panic异常
 // if err := recover(); err != nil {
 // strerr := fmt.Sprintf("%s", err)
 // //发消息给客户端
 // ErrorST := Proto2.G_Error_All{
 // Protocol: Proto.G_Error_Proto, // 主协议
 // Protocol2: Proto2.G_Error_All_Proto, // 子协议
 // ErrCode: "80006",
 // ErrMsg: "亲,您发的数据的格式不对!" + strerr,
 // }
 // // 发送给玩家数据
 // fmt.Println("Global server的主协议!!!", ErrorST)
 // }
 // }()
 // 协议处理
 switch protocol {
 case float64(Proto.G_GameGlobal_Proto):
 { // Global Server 主要协议处理
 fmt.Println("Global server 主协议!!!")
 HandleCltProtocol2Glogbal(protocol2, ProtocolData)
 }
 default:
 panic("主协议:不存在!!!")
 }
 return
}
// 子协议的处理
func HandleCltProtocol2Glogbal(protocol2 interface{}, ProtocolData map[string]interface{}) {
 switch protocol2 {
 case float64(Proto2.GW2G_ConnServerProto2):
 { // 网关返回数据
 fmt.Println("gateway server 返回给global server 数据信息!!!")
 }
 case float64(Proto2.G2GW_PlayerEntryHallProto2):
 {
 G2GW_PlayerEntryHallProto2Fucn(Conn, ProtocolData)
 }
 case float64(Proto2.G2GW_PlayerMatchGameProto2):
 {
 fmt.Println("玩家请求玩家匹配!")
 G2GW_PlayerMatchGameProto2Fucn(Conn, ProtocolData)
 }
 case float64(Proto2.GW2G_PlayerQuitMatchGameProto2):
 {
 fmt.Println("玩家主动退出匹配!")
 G2GW_PlayerQuitMatchGameProto2Fucn(Conn, ProtocolData)
 }
 default:
 panic("子协议:不存在!!!")
 }
 return
}
// 玩家主动退出匹配
func G2GW_PlayerQuitMatchGameProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {
 if ProtocolData["OpenID"] == nil {
 panic("玩家主动退出匹配!")
 return
 }
 StrOpenID := ProtocolData["OpenID"].(string)
 // 玩家主动退出
 match.SetQuitMatch(StrOpenID)
 // 发送消息
 data_send := &Proto2.G2GW_PlayerQuitMatchGame{
 Protocol: Proto.G_GameGlobal_Proto,
 Protocol2: Proto2.G2GW_PlayerQuitMatchGameProto2,
 OpenID: StrOpenID,
 ResultID: 0,
 }
 PlayerSendToServer(conn, data_send)
 return
}
// 玩家匹配
func G2GW_PlayerMatchGameProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {
 if ProtocolData["OpenID"] == nil ||
 ProtocolData["RoomID"] == nil ||
 ProtocolData["Itype"] == nil {
 panic("选择游戏对战类型协议参数错误!")
 return
 }
 StrOpenID := ProtocolData["OpenID"].(string)
 StrRoomID := ProtocolData["RoomID"].(string) // 匹配数据
 StrItype := ProtocolData["Itype"].(string) // 1 是正常匹配 2 是快速匹配
 // 数据
 data_send := &Proto2.GW2G_PlayerMatchGame{
 Protocol: Proto.G_GameGlobal_Proto, // 游戏主要协议
 Protocol2: Proto2.GW2G_PlayerMatchGameProto2,
 OpenID: StrOpenID, // 玩家唯一标识
 // RoomUID: 0,
 // MatchPlayer: nil,
 // ChessBoard: {{}, {}, {}, {}},
 ResultID: 0,
 }
 if match.GetMatchQueue(StrOpenID) {
 data_send.ResultID = Error.IsMatch
 PlayerSendToServer(conn, data_send)
 return
 }
 match.SetMatchQueue(StrOpenID)
 if StrItype == "2" { //快速匹配
 PlayerSendToServer(conn, data_send)
 return
 }
 data := conf.RoomListDatabak[StrRoomID]
 fmt.Println("针对某房间ID去获取,相应的数据的", conf.RoomListDatabak, data.NeedLev, StrRoomID)
 dataplayer := DB_Save_RoleSTBak(StrOpenID)
 match.Putdata(dataplayer)
 s := string([]byte(data.NeedLev)[2:])
 if util.Str2int_LollipopGo(s) > dataplayer.Lev {
 data_send.ResultID = Error.Lev_lack
 PlayerSendToServer(conn, data_send)
 return
 } else if util.Str2int_LollipopGo(data.NeedPiece) > dataplayer.CoinNum {
 data_send.ResultID = Error.Coin_lack
 PlayerSendToServer(conn, data_send)
 return
 }
 if len(match.MatchData) > 1 {
 dar := <-match.MatchData_Chan
 data_send.MatchPlayer = dar
 fmt.Println(data_send)
 PlayerSendToServer(conn, data_send)
 match.DelMatchQueue(StrOpenID)
 } else {
 go PlayerMatchTime(conn, StrOpenID, data_send)
 }
 return
}
func PlayerMatchTime(conn *websocket.Conn, OpenID string, data_send *Proto2.GW2G_PlayerMatchGame) {
 icount := 0
 for {
 select {
 case <-time.After(match.PlaterMatchSpeed):
 {
 fmt.Println(icount)
 if icount >= 30 {
 PlayerSendToServer(conn, data_send)
 return
 }
 if len(match.MatchData_Chan) > 1 {
 dar := <-match.MatchData_Chan
 data_send.MatchPlayer = dar
 fmt.Println(data_send)
 PlayerSendToServer(conn, data_send)
 match.DelMatchQueue(OpenID)
 return
 }
 icount++
 }
 }
 }
}
// 保存数据都DB 人物信息
func DB_Save_RoleSTBak(openid string) *player.PlayerSt {
 args := player.PlayerSt{
 OpenID: openid,
 }
 var reply *player.PlayerSt
 // 异步调用【结构的方法】
 if ConnRPC != nil {
 // ConnRPC.Call("Arith.GetPlayerST2DB", args, &reply) 同步调用
 divCall := ConnRPC.Go("Arith.GetPlayerST2DB", args, &reply, nil)
 replyCall := <-divCall.Done
 _ = replyCall.Reply
 } else {
 fmt.Println("ConnRPC == nil")
 }
 return reply
}
func G2GW_PlayerEntryHallProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {
 StrUID := ProtocolData["UID"].(string)
 StrOpenID := ProtocolData["OpenID"].(string)
 StrPlayerName := ProtocolData["PlayerName"].(string)
 StrHeadUrl := ProtocolData["HeadUrl"].(string)
 StrSex := ProtocolData["Sex"].(string)
 StrConstellation := ProtocolData["Constellation"].(string)
 StrPlayerSchool := ProtocolData["PlayerSchool"].(string)
 StrToken := ProtocolData["Token"].(string)
 _ = StrToken
 // 获取在线人数
 ddd := make(map[string]interface{})
 csv.M_CSV.LollipopGo_RLockRange(ddd)
 // 查询数据库,找出游戏服务器的uid信息
 // 返回的数据操作
 datadb := DB_Save_RoleST(StrUID, StrPlayerName, StrHeadUrl, StrPlayerSchool, StrSex, StrConstellation, 0, 0, 2000, 0, 0)
 fmt.Println("--------------------------:", datadb)
 // 个人数据
 personalmap := make(map[string]*player.PlayerSt)
 personalmap["1"] = &datadb
 _ = personalmap["1"].OpenID
 // 组装数据
 data := &Proto2.GW2G_PlayerEntryHall{
 Protocol: Proto.G_GameGlobal_Proto, // 游戏主要协议
 Protocol2: Proto2.GW2G_PlayerEntryHallProto2,
 OpenID: StrOpenID,
 PlayerName: StrPlayerName,
 HeadUrl: StrHeadUrl,
 Constellation: StrConstellation,
 Sex: StrSex,
 GamePlayerNum: ddd,
 RacePlayerNum: nil,
 Personal: personalmap,
 DefaultMsg: nil,
 DefaultAward: nil,
 }
 fmt.Println(data)
 PlayerSendToServer(conn, data)
 // 保存玩家的数据 -- 主要是为了
 return
}
// 保存数据都DB 人物信息
func DB_Save_RoleST(uid, strname, HeadURL, StrPlayerSchool, Sex, Constellation string, Lev, HallExp, CoinNum, MasonryNum, MCard int) player.PlayerSt {
 args := player.PlayerSt{
 UID: util.Str2int_LollipopGo(uid),
 VIP_Lev: 0,
 Name: strname,
 HeadURL: HeadURL,
 Sex: Sex,
 PlayerSchool: StrPlayerSchool,
 Lev: Lev,
 HallExp: HallExp,
 CoinNum: CoinNum,
 MasonryNum: MasonryNum,
 MCard: MCard,
 Constellation: Constellation,
 OpenID: util.MD5_LollipopGO(uid),
 }
 var reply player.PlayerSt
 // 异步调用【结构的方法】
 if ConnRPC != nil {
 // ConnRPC.Call("Arith.SavePlayerST2DB", args, &reply) 同步调用
 divCall := ConnRPC.Go("Arith.SavePlayerST2DB", args, &reply, nil)
 replyCall := <-divCall.Done
 _ = replyCall.Reply
 } else {
 fmt.Println("ConnRPC == nil")
 }
 return reply
}
func initConn(conn *websocket.Conn) {
 data := &Proto2.G2GW_ConnServer{
 Protocol: Proto.G_GameGlobal_Proto,
 Protocol2: Proto2.G2GW_ConnServerProto2,
 ServerID: util.MD5_LollipopGO("8894" + "Global server"),
 }
 PlayerSendToServer(conn, data)
 return
}

每天坚持学习1小时Go语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!


社区交流群:221273219
Golang语言社区论坛 :
www.Golang.Ltd
LollipopGo游戏服务器地址:
https://github.com/Golangltd/LollipopGo
社区视频课程课件GIT地址:
https://github.com/Golangltd/codeclass


Golang语言社区

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:Golang语言社区

查看原文:LollipopGo开源游戏服务器框架--global服务器源码

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2861 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏