大家好,我是彬哥,本节给大家讲下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 :=

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

{

fmt.Println(icount)

if icount >= 30 {

PlayerSendToServer(conn, data_send)

return

}

if len(match.MatchData_Chan) > 1 {

dar :=

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 :=

_ = 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 :=

_ = 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语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!

Golang语言社区