go 服务器 源码,LollipopGo开源游戏服务器框架--global服务器源码
大家好,我是彬哥,本節給大家講下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語言社區
總結
以上是生活随笔為你收集整理的go 服务器 源码,LollipopGo开源游戏服务器框架--global服务器源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云500服务器内部错误,腾讯云服务器
- 下一篇: 装服务器显示磁盘脱机,服务器磁盘处于脱机