first commit
This commit is contained in:
204
server/chatserver/controller/chat.go
Normal file
204
server/chatserver/controller/chat.go
Normal file
@@ -0,0 +1,204 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/chatserver/logic"
|
||||
"slgserver/server/chatserver/proto"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var DefaultChat = Chat{
|
||||
worldGroup: logic.NewGroup(),
|
||||
unionGroups: make(map[int]*logic.Group),
|
||||
ridToUnionGroups: make(map[int]int),
|
||||
}
|
||||
|
||||
type Chat struct {
|
||||
unionMutex sync.RWMutex
|
||||
worldGroup *logic.Group //世界频道
|
||||
unionGroups map[int]*logic.Group //联盟频道
|
||||
ridToUnionGroups map[int]int //rid对应的联盟频道
|
||||
}
|
||||
|
||||
func (this*Chat) InitRouter(r *net.Router) {
|
||||
g := r.Group("chat").Use(middleware.ElapsedTime(), middleware.Log())
|
||||
|
||||
g.AddRouter("login", this.login)
|
||||
g.AddRouter("logout", this.logout, middleware.CheckRId())
|
||||
g.AddRouter("chat", this.chat, middleware.CheckRId())
|
||||
g.AddRouter("history", this.history, middleware.CheckRId())
|
||||
g.AddRouter("join", this.join, middleware.CheckRId())
|
||||
g.AddRouter("exit", this.exit, middleware.CheckRId())
|
||||
}
|
||||
|
||||
func (this*Chat) login(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.LoginReq{}
|
||||
rspObj := &proto.LoginRsp{}
|
||||
rsp.Body.Code = constant.OK
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rspObj.RId = reqObj.RId
|
||||
rspObj.NickName = reqObj.NickName
|
||||
|
||||
sess, err := util.ParseSession(reqObj.Token)
|
||||
if err != nil{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
if sess.IsValid() == false || sess.Id != reqObj.RId{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
net.ConnMgr.RoleEnter(req.Conn, reqObj.RId)
|
||||
|
||||
this.worldGroup.Enter(logic.NewUser(reqObj.RId, reqObj.NickName))
|
||||
}
|
||||
|
||||
func (this*Chat) logout(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.LogoutReq{}
|
||||
rspObj := &proto.LogoutRsp{}
|
||||
rsp.Body.Code = constant.OK
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rspObj.RId = reqObj.RId
|
||||
|
||||
net.ConnMgr.UserLogout(req.Conn)
|
||||
this.worldGroup.Exit(reqObj.RId)
|
||||
}
|
||||
|
||||
func (this*Chat) chat(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ChatReq{}
|
||||
rspObj := &proto.ChatMsg{}
|
||||
rsp.Body.Code = constant.OK
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
|
||||
p, _ := req.Conn.GetProperty("rid")
|
||||
rid := p.(int)
|
||||
if reqObj.Type == 0 {
|
||||
//世界聊天
|
||||
rsp.Body.Msg = this.worldGroup.PutMsg(reqObj.Msg, rid, 0)
|
||||
}else if reqObj.Type == 1{
|
||||
//联盟聊天
|
||||
this.unionMutex.RLock()
|
||||
id, ok := this.ridToUnionGroups[rid]
|
||||
if ok {
|
||||
g, ok := this.unionGroups[id]
|
||||
if ok {
|
||||
g.PutMsg(reqObj.Msg, rid, 1)
|
||||
}else{
|
||||
slog.Warn("chat not found rid in unionGroups", "rid", rid)
|
||||
}
|
||||
}else{
|
||||
slog.Warn("chat not found rid in ridToUnionGroups", "rid", rid)
|
||||
}
|
||||
this.unionMutex.RUnlock()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//历史记录
|
||||
func (this*Chat) history(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.HistoryReq{}
|
||||
rspObj := &proto.HistoryRsp{}
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rspObj.Msgs = []proto.ChatMsg{}
|
||||
p, _ := req.Conn.GetProperty("rid")
|
||||
rid := p.(int)
|
||||
|
||||
if reqObj.Type == 0 {
|
||||
r := this.worldGroup.History()
|
||||
rspObj.Msgs = r
|
||||
}else if reqObj.Type == 1 {
|
||||
this.unionMutex.RLock()
|
||||
id, ok := this.ridToUnionGroups[rid]
|
||||
if ok {
|
||||
g, ok := this.unionGroups[id]
|
||||
if ok {
|
||||
rspObj.Msgs = g.History()
|
||||
}
|
||||
}
|
||||
this.unionMutex.RUnlock()
|
||||
}
|
||||
rspObj.Type = reqObj.Type
|
||||
rsp.Body.Msg = rspObj
|
||||
}
|
||||
|
||||
func (this*Chat) join(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.JoinReq{}
|
||||
rspObj := &proto.JoinRsp{}
|
||||
rsp.Body.Code = constant.OK
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.Type = reqObj.Type
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
p, _ := req.Conn.GetProperty("rid")
|
||||
rid := p.(int)
|
||||
if reqObj.Type == 1 {
|
||||
u := this.worldGroup.GetUser(rid)
|
||||
if u == nil {
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
this.unionMutex.Lock()
|
||||
gId, ok := this.ridToUnionGroups[rid]
|
||||
if ok {
|
||||
if gId != reqObj.Id {
|
||||
//联盟聊天只能有一个,顶掉旧的
|
||||
if g,ok := this.unionGroups[gId]; ok {
|
||||
g.Exit(rid)
|
||||
}
|
||||
|
||||
_, ok = this.unionGroups[reqObj.Id]
|
||||
if ok == false {
|
||||
this.unionGroups[reqObj.Id] = logic.NewGroup()
|
||||
}
|
||||
this.ridToUnionGroups[rid] = reqObj.Id
|
||||
this.unionGroups[reqObj.Id].Enter(u)
|
||||
}
|
||||
}else{
|
||||
//新加入
|
||||
_, ok = this.unionGroups[reqObj.Id]
|
||||
if ok == false {
|
||||
this.unionGroups[reqObj.Id] = logic.NewGroup()
|
||||
}
|
||||
this.ridToUnionGroups[rid] = reqObj.Id
|
||||
this.unionGroups[reqObj.Id].Enter(u)
|
||||
}
|
||||
this.unionMutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (this*Chat) exit(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ExitReq{}
|
||||
rspObj := &proto.ExitRsp{}
|
||||
rsp.Body.Code = constant.OK
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.Type = reqObj.Type
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
p, _ := req.Conn.GetProperty("rid")
|
||||
rid := p.(int)
|
||||
|
||||
if reqObj.Type == 1 {
|
||||
this.unionMutex.Lock()
|
||||
id, ok := this.ridToUnionGroups[rid]
|
||||
if ok {
|
||||
g, ok := this.unionGroups[id]
|
||||
if ok {
|
||||
g.Exit(rid)
|
||||
}
|
||||
}
|
||||
delete(this.ridToUnionGroups, rid)
|
||||
this.unionMutex.Unlock()
|
||||
}
|
||||
}
|
||||
20
server/chatserver/init.go
Normal file
20
server/chatserver/init.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package chatserver
|
||||
|
||||
import (
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/chatserver/controller"
|
||||
)
|
||||
|
||||
var MyRouter = &net.Router{}
|
||||
|
||||
func Init() {
|
||||
db.TestDB()
|
||||
|
||||
//全部初始化完才注册路由,防止服务器还没启动就绪收到请求
|
||||
initRouter()
|
||||
}
|
||||
|
||||
func initRouter() {
|
||||
controller.DefaultChat.InitRouter(MyRouter)
|
||||
}
|
||||
22
server/chatserver/logic/entity.go
Normal file
22
server/chatserver/logic/entity.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package logic
|
||||
|
||||
import "time"
|
||||
|
||||
type User struct {
|
||||
rid int
|
||||
nickName string
|
||||
}
|
||||
|
||||
func NewUser(rid int, nickName string) *User {
|
||||
return &User{
|
||||
rid: rid,
|
||||
nickName: nickName,
|
||||
}
|
||||
}
|
||||
|
||||
type Msg struct {
|
||||
RId int `json:"rid"`
|
||||
NickName string `json:"nickName"`
|
||||
Msg string `json:"msg"`
|
||||
Time time.Time `json:"time"`
|
||||
}
|
||||
79
server/chatserver/logic/group.go
Normal file
79
server/chatserver/logic/group.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"slgserver/net"
|
||||
"slgserver/server/chatserver/proto"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Group struct {
|
||||
userMutex sync.RWMutex
|
||||
msgMutex sync.RWMutex
|
||||
users map[int]*User
|
||||
msgs ItemQueue
|
||||
}
|
||||
|
||||
func NewGroup() *Group {
|
||||
return &Group{users: map[int]*User{}}
|
||||
}
|
||||
|
||||
func (this*Group) Enter(u *User) {
|
||||
this.userMutex.Lock()
|
||||
defer this.userMutex.Unlock()
|
||||
this.users[u.rid] = u
|
||||
}
|
||||
|
||||
func (this*Group) Exit(rid int) {
|
||||
this.userMutex.Lock()
|
||||
defer this.userMutex.Unlock()
|
||||
delete(this.users, rid)
|
||||
}
|
||||
|
||||
func (this*Group) GetUser(rid int) *User {
|
||||
this.userMutex.Lock()
|
||||
defer this.userMutex.Unlock()
|
||||
return this.users[rid]
|
||||
}
|
||||
|
||||
func (this*Group) PutMsg(text string, rid int, t int8) *proto.ChatMsg {
|
||||
|
||||
this.userMutex.RLock()
|
||||
u, ok := this.users[rid]
|
||||
this.userMutex.RUnlock()
|
||||
if ok == false{
|
||||
return nil
|
||||
}
|
||||
|
||||
msg := &Msg{Msg: text, RId: rid, Time: time.Now(), NickName: u.nickName}
|
||||
this.msgMutex.Lock()
|
||||
size := this.msgs.Size()
|
||||
if size > 100 {
|
||||
this.msgs.Dequeue()
|
||||
}
|
||||
this.msgs.Enqueue(msg)
|
||||
this.msgMutex.Unlock()
|
||||
|
||||
//广播
|
||||
this.userMutex.RLock()
|
||||
c := &proto.ChatMsg{RId: msg.RId, NickName: msg.NickName, Time: msg.Time.Unix(), Msg: msg.Msg, Type: t}
|
||||
for _, user := range this.users {
|
||||
net.ConnMgr.PushByRoleId(user.rid, "chat.push", c)
|
||||
}
|
||||
this.userMutex.RUnlock()
|
||||
return c
|
||||
}
|
||||
|
||||
func (this*Group) History() []proto.ChatMsg {
|
||||
r := make([]proto.ChatMsg, 0)
|
||||
this.msgMutex.RLock()
|
||||
items := this.msgs.items
|
||||
for _, item := range items {
|
||||
msg := item.(*Msg)
|
||||
c := proto.ChatMsg{RId: msg.RId, NickName: msg.NickName, Time: msg.Time.Unix(), Msg: msg.Msg}
|
||||
r = append(r, c)
|
||||
}
|
||||
this.msgMutex.RUnlock()
|
||||
|
||||
return r
|
||||
}
|
||||
45
server/chatserver/logic/queue.go
Normal file
45
server/chatserver/logic/queue.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package logic
|
||||
|
||||
type Item interface {
|
||||
}
|
||||
|
||||
// Item the type of the queue
|
||||
type ItemQueue struct {
|
||||
items []Item
|
||||
}
|
||||
|
||||
type ItemQueuer interface {
|
||||
New() ItemQueue
|
||||
Enqueue(t Item)
|
||||
Dequeue() *Item
|
||||
IsEmpty() bool
|
||||
Size() int
|
||||
}
|
||||
|
||||
// New creates a new ItemQueue
|
||||
func (s *ItemQueue) New() *ItemQueue {
|
||||
s.items = []Item{}
|
||||
return s
|
||||
}
|
||||
|
||||
// Enqueue adds an Item to the end of the queue
|
||||
func (s *ItemQueue) Enqueue(t Item) {
|
||||
s.items = append(s.items, t)
|
||||
}
|
||||
|
||||
// dequeue
|
||||
func (s *ItemQueue) Dequeue() *Item {
|
||||
item := s.items[0] // 先进先出
|
||||
s.items = s.items[1:len(s.items)]
|
||||
|
||||
return &item
|
||||
}
|
||||
|
||||
func (s *ItemQueue) IsEmpty() bool {
|
||||
return len(s.items) == 0
|
||||
}
|
||||
|
||||
// Size returns the number of Items in the queue
|
||||
func (s *ItemQueue) Size() int {
|
||||
return len(s.items)
|
||||
}
|
||||
64
server/chatserver/proto/chat.go
Normal file
64
server/chatserver/proto/chat.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package proto
|
||||
|
||||
type LoginReq struct {
|
||||
RId int `json:"rid"`
|
||||
NickName string `json:"nickName"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type LoginRsp struct {
|
||||
RId int `json:"rid"`
|
||||
NickName string `json:"nickName"`
|
||||
}
|
||||
|
||||
type LogoutReq struct {
|
||||
RId int `json:"RId"`
|
||||
}
|
||||
|
||||
type LogoutRsp struct {
|
||||
RId int `json:"RId"`
|
||||
}
|
||||
|
||||
type ChatReq struct {
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
|
||||
type ChatMsg struct {
|
||||
RId int `json:"rid"`
|
||||
NickName string `json:"nickName"`
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
Msg string `json:"msg"`
|
||||
Time int64 `json:"time"`
|
||||
}
|
||||
|
||||
|
||||
type HistoryReq struct {
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
}
|
||||
|
||||
type HistoryRsp struct {
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
Msgs []ChatMsg `json:"msgs"`
|
||||
}
|
||||
|
||||
type JoinReq struct {
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
type JoinRsp struct {
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
type ExitReq struct {
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
type ExitRsp struct {
|
||||
Type int8 `json:"type"` //0世界聊天、1联盟聊天
|
||||
Id int `json:"id"`
|
||||
}
|
||||
205
server/gateserver/controller/handle.go
Normal file
205
server/gateserver/controller/handle.go
Normal file
@@ -0,0 +1,205 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"log/slog"
|
||||
"slgserver/config"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
chat_proto "slgserver/server/chatserver/proto"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var GHandle = Handle{
|
||||
proxys: make(map[string]map[int64]*net.ProxyClient),
|
||||
}
|
||||
|
||||
type Handle struct {
|
||||
proxyMutex sync.Mutex
|
||||
proxys map[string]map[int64]*net.ProxyClient
|
||||
slgProxy string
|
||||
chatProxy string
|
||||
loginProxy string
|
||||
}
|
||||
|
||||
func isAccount(msgName string) bool {
|
||||
sArr := strings.Split(msgName, ".")
|
||||
prefix := ""
|
||||
if len(sArr) == 2{
|
||||
prefix = sArr[0]
|
||||
}
|
||||
if prefix == "account"{
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isChat(msgName string) bool {
|
||||
sArr := strings.Split(msgName, ".")
|
||||
prefix := ""
|
||||
if len(sArr) == 2{
|
||||
prefix = sArr[0]
|
||||
}
|
||||
if prefix == "chat"{
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (this*Handle) InitRouter(r *net.Router) {
|
||||
this.init()
|
||||
g := r.Group("*").Use(middleware.ElapsedTime(), middleware.Log())
|
||||
g.AddRouter("*", this.all)
|
||||
}
|
||||
|
||||
func (this*Handle) init() {
|
||||
this.slgProxy = config.GetString("gateserver.slg_proxy", "ws://127.0.0.1:8001")
|
||||
this.chatProxy = config.GetString("gateserver.chat_proxy", "ws://127.0.0.1:8002")
|
||||
this.loginProxy = config.GetString("gateserver.login_proxy", "ws://127.0.0.1:8003")
|
||||
}
|
||||
|
||||
func (this*Handle) onPush(conn *net.ClientConn, body *net.RspBody) {
|
||||
gc, err := conn.GetProperty("gateConn")
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
gateConn := gc.(net.WSConn)
|
||||
gateConn.Push(body.Name, body.Msg)
|
||||
}
|
||||
|
||||
func (this*Handle) onProxyClose(conn *net.ClientConn) {
|
||||
p, err := conn.GetProperty("proxy")
|
||||
if err == nil {
|
||||
proxyStr := p.(string)
|
||||
this.proxyMutex.Lock()
|
||||
_, ok := this.proxys[proxyStr]
|
||||
if ok {
|
||||
c, err := conn.GetProperty("cid")
|
||||
if err == nil{
|
||||
cid := c.(int64)
|
||||
delete(this.proxys[proxyStr], cid)
|
||||
}
|
||||
}
|
||||
this.proxyMutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (this*Handle) OnServerConnClose (conn net.WSConn){
|
||||
c, err := conn.GetProperty("cid")
|
||||
arr := make([]*net.ProxyClient, 0)
|
||||
|
||||
if err == nil{
|
||||
cid := c.(int64)
|
||||
this.proxyMutex.Lock()
|
||||
for _, m := range this.proxys {
|
||||
proxy, ok := m[cid]
|
||||
if ok {
|
||||
arr = append(arr, proxy)
|
||||
}
|
||||
delete(m, cid)
|
||||
}
|
||||
this.proxyMutex.Unlock()
|
||||
}
|
||||
|
||||
for _, client := range arr {
|
||||
client.Close()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this*Handle) all(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
slog.Info("gateserver handle all begin",
|
||||
"proxyStr", req.Body.Proxy,
|
||||
"msgName", req.Body.Name)
|
||||
this.deal(req, rsp)
|
||||
|
||||
if req.Body.Name == "role.enterServer" && rsp.Body.Code == constant.OK {
|
||||
//登录聊天服
|
||||
rspObj := &proto.EnterServerRsp{}
|
||||
mapstructure.Decode(rsp.Body.Msg, rspObj)
|
||||
r := &chat_proto.LoginReq{RId: rspObj.Role.RId, NickName: rspObj.Role.NickName, Token: rspObj.Token}
|
||||
reqBody := &net.ReqBody{Seq: 0, Name: "chat.login", Msg: r, Proxy: ""}
|
||||
rspBody := &net.RspBody{Seq: 0, Name: "chat.login", Msg: r, Code: 0}
|
||||
this.deal(&net.WsMsgReq{Body: reqBody, Conn:req.Conn}, &net.WsMsgRsp{Body: rspBody})
|
||||
}
|
||||
|
||||
slog.Info("gateserver handle all end",
|
||||
"proxyStr", req.Body.Proxy,
|
||||
"msgName", req.Body.Name)
|
||||
}
|
||||
|
||||
func (this*Handle) deal(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
//协议转发
|
||||
proxyStr := req.Body.Proxy
|
||||
if isAccount(req.Body.Name){
|
||||
proxyStr = this.loginProxy
|
||||
}else if isChat(req.Body.Name){
|
||||
proxyStr = this.chatProxy
|
||||
} else{
|
||||
proxyStr = this.slgProxy
|
||||
}
|
||||
|
||||
if proxyStr == ""{
|
||||
rsp.Body.Code = constant.ProxyNotInConnect
|
||||
return
|
||||
}
|
||||
|
||||
this.proxyMutex.Lock()
|
||||
_, ok := this.proxys[proxyStr]
|
||||
if ok == false {
|
||||
this.proxys[proxyStr] = make(map[int64]*net.ProxyClient)
|
||||
}
|
||||
|
||||
var err error
|
||||
var proxy *net.ProxyClient
|
||||
d, _ := req.Conn.GetProperty("cid")
|
||||
cid := d.(int64)
|
||||
proxy, ok = this.proxys[proxyStr][cid]
|
||||
this.proxyMutex.Unlock()
|
||||
|
||||
if ok == false {
|
||||
proxy = net.NewProxyClient(proxyStr)
|
||||
|
||||
this.proxyMutex.Lock()
|
||||
this.proxys[proxyStr][cid] = proxy
|
||||
this.proxyMutex.Unlock()
|
||||
|
||||
//发起链接,这里是阻塞的,所以不要上锁
|
||||
err = proxy.Connect()
|
||||
if err == nil{
|
||||
proxy.SetProperty("cid", cid)
|
||||
proxy.SetProperty("proxy", proxyStr)
|
||||
proxy.SetProperty("gateConn", req.Conn)
|
||||
proxy.SetOnPush(this.onPush)
|
||||
proxy.SetOnClose(this.onProxyClose)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
this.proxyMutex.Lock()
|
||||
delete(this.proxys[proxyStr], cid)
|
||||
this.proxyMutex.Unlock()
|
||||
rsp.Body.Code = constant.ProxyConnectError
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Body.Seq = req.Body.Seq
|
||||
rsp.Body.Name = req.Body.Name
|
||||
|
||||
r, err := proxy.Send(req.Body.Name, req.Body.Msg)
|
||||
if err == nil{
|
||||
rsp.Body.Code = r.Code
|
||||
rsp.Body.Msg = r.Msg
|
||||
}else{
|
||||
rsp.Body.Code = constant.ProxyConnectError
|
||||
rsp.Body.Msg = nil
|
||||
}
|
||||
}
|
||||
|
||||
19
server/gateserver/init.go
Normal file
19
server/gateserver/init.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package gateserver
|
||||
|
||||
import (
|
||||
"slgserver/net"
|
||||
"slgserver/server/gateserver/controller"
|
||||
)
|
||||
|
||||
var MyRouter = &net.Router{}
|
||||
|
||||
func Init() {
|
||||
//全部初始化完才注册路由,防止服务器还没启动就绪收到请求
|
||||
initRouter()
|
||||
}
|
||||
|
||||
func initRouter() {
|
||||
controller.GHandle.InitRouter(MyRouter)
|
||||
}
|
||||
|
||||
|
||||
59
server/httpserver/controller/account.go
Normal file
59
server/httpserver/controller/account.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
myhttp "slgserver/server/httpserver"
|
||||
"slgserver/server/httpserver/logic"
|
||||
"slgserver/server/httpserver/middleware"
|
||||
)
|
||||
|
||||
type AccountController struct{}
|
||||
|
||||
func (self AccountController) RegisterRoutes(g *gin.RouterGroup) {
|
||||
g.Use(middleware.Cors())
|
||||
|
||||
g.Any("/account/register", self.register)
|
||||
g.Any("/account/changepwd", self.changePwd)
|
||||
g.Any("/account/forgetpwd", self.forgetPwd)
|
||||
g.Any("/account/resetpwd", self.resetPwd)
|
||||
}
|
||||
|
||||
func (self AccountController) register(ctx *gin.Context) {
|
||||
slog.Info("register")
|
||||
data := make(map[string]interface{})
|
||||
if err := logic.DefaultUser.CreateUser(ctx); err != nil {
|
||||
data["code"] = err.(*myhttp.MyError).Id()
|
||||
data["errmsg"] = err.(*myhttp.MyError).Error()
|
||||
}else{
|
||||
data["code"] = constant.OK
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, data)
|
||||
}
|
||||
|
||||
func (self AccountController) forgetPwd(ctx *gin.Context) {
|
||||
slog.Info("forgetPwd")
|
||||
ctx.String(http.StatusOK, "forgetPwd")
|
||||
}
|
||||
|
||||
func (self AccountController) changePwd(ctx *gin.Context) {
|
||||
slog.Info("changePwd")
|
||||
data := make(map[string]interface{})
|
||||
if err := logic.DefaultUser.ChangePassword(ctx); err != nil {
|
||||
data["code"] = err.(*myhttp.MyError).Id()
|
||||
data["errmsg"] = err.(*myhttp.MyError).Error()
|
||||
}else{
|
||||
data["code"] = constant.OK
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, data)
|
||||
}
|
||||
|
||||
func (self AccountController) resetPwd(ctx *gin.Context) {
|
||||
slog.Info("resetPwd")
|
||||
ctx.String(http.StatusOK, "resetPwd")
|
||||
}
|
||||
|
||||
88
server/httpserver/logic/account.go
Normal file
88
server/httpserver/logic/account.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"math/rand"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
myhttp "slgserver/server/httpserver"
|
||||
"slgserver/server/loginserver/model"
|
||||
"slgserver/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserLogic struct{}
|
||||
var DefaultUser = UserLogic{}
|
||||
|
||||
func (self UserLogic) CreateUser(ctx *gin.Context) error {
|
||||
account := ctx.Query("username")
|
||||
pwd := ctx.Query("password")
|
||||
hardware := ctx.Query("hardware")
|
||||
|
||||
if len(account) > 0 && len(pwd) > 0 {
|
||||
if self.UserExists("username", account) {
|
||||
return myhttp.New("账号已经存在", constant.UserExist)
|
||||
}
|
||||
|
||||
passcode := fmt.Sprintf("%x", rand.Int31())
|
||||
user := &model.User{
|
||||
Username: account,
|
||||
Passcode: passcode,
|
||||
Passwd: util.Password(pwd, passcode),
|
||||
Hardware: hardware,
|
||||
Ctime: time.Now(),
|
||||
Mtime: time.Now()}
|
||||
|
||||
if _, err := db.MasterDB.Insert(user); err != nil {
|
||||
return myhttp.New("数据库出错", constant.DBError)
|
||||
} else{
|
||||
return nil
|
||||
}
|
||||
}else{
|
||||
return myhttp.New("用户名或密码是空", constant.InvalidParam)
|
||||
}
|
||||
}
|
||||
|
||||
func (self UserLogic) ChangePassword(ctx *gin.Context) error {
|
||||
account := ctx.Query("username")
|
||||
pwd := ctx.Query("password")
|
||||
newpwd := ctx.Query("newpassword")
|
||||
|
||||
user := &model.User{}
|
||||
if len(account) > 0 && len(pwd) > 0 && len(newpwd) > 0{
|
||||
if _, err := db.MasterDB.Where("username=?", account).Get(user); err != nil {
|
||||
return myhttp.New("数据库出错", constant.DBError)
|
||||
}else{
|
||||
if util.Password(pwd, user.Passcode) == user.Passwd {
|
||||
passcode := fmt.Sprintf("%x", rand.Int31())
|
||||
changeData := map[string]interface{}{
|
||||
"passwd": util.Password(newpwd, passcode),
|
||||
"passcode": passcode,
|
||||
"Mtime": time.Now(),
|
||||
}
|
||||
|
||||
if _, err := db.MasterDB.Table(user).Where("username=?", account).Update(changeData); err !=nil {
|
||||
return myhttp.New("数据库出错", constant.DBError)
|
||||
}else{
|
||||
return nil
|
||||
}
|
||||
|
||||
}else{
|
||||
return myhttp.New("原密码错误", constant.PwdIncorrect)
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
return myhttp.New("用户名或密码是空", constant.InvalidParam)
|
||||
}
|
||||
}
|
||||
|
||||
func (UserLogic) UserExists(field, val string) bool {
|
||||
userLogin := &model.User{}
|
||||
_, err := db.MasterDB.Where(field+"=?", val).Get(userLogin)
|
||||
if err != nil || userLogin.UId == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
22
server/httpserver/middleware/cors.go
Normal file
22
server/httpserver/middleware/cors.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Cors() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS, POST, PUT, DELETE")
|
||||
ctx.Writer.Header().Set("Content-Type", "application/json")
|
||||
|
||||
if ctx.Request.Method == "OPTIONS" {
|
||||
ctx.AbortWithStatus(204)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
21
server/httpserver/myerror.go
Normal file
21
server/httpserver/myerror.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package httpserver
|
||||
|
||||
type MyError struct {
|
||||
err string
|
||||
id int
|
||||
}
|
||||
|
||||
func New(err string, id int) error {
|
||||
return &MyError{err: err, id: id}
|
||||
}
|
||||
|
||||
func (self *MyError) Error() string {
|
||||
return self.err
|
||||
}
|
||||
|
||||
func (self *MyError) Id() int {
|
||||
return self.id
|
||||
}
|
||||
|
||||
|
||||
|
||||
189
server/loginserver/controller/account.go
Normal file
189
server/loginserver/controller/account.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
"log/slog"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/loginserver/model"
|
||||
"slgserver/server/loginserver/proto"
|
||||
"slgserver/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
var DefaultAccount = Account{}
|
||||
|
||||
type Account struct {
|
||||
}
|
||||
|
||||
func (this*Account) InitRouter(r *net.Router) {
|
||||
g := r.Group("account").Use(middleware.ElapsedTime(), middleware.Log())
|
||||
|
||||
g.AddRouter("login", this.login)
|
||||
g.AddRouter("reLogin", this.reLogin)
|
||||
g.AddRouter("logout", this.logout, middleware.CheckLogin())
|
||||
g.AddRouter("serverList", this.serverList, middleware.CheckLogin())
|
||||
}
|
||||
|
||||
func (this*Account) login(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
reqObj := &proto.LoginReq{}
|
||||
rspObj := &proto.LoginRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
user := &model.User{}
|
||||
ok, err := db.MasterDB.Table(user).Where("username=?", reqObj.Username).Get(user)
|
||||
if err!= nil {
|
||||
slog.Error("login db error",
|
||||
"username", reqObj.Username,
|
||||
"error", err)
|
||||
|
||||
rsp.Body.Code = constant.DBError
|
||||
}else{
|
||||
if ok {
|
||||
pwd := util.Password(reqObj.Password, user.Passcode)
|
||||
if pwd != user.Passwd{
|
||||
//密码不正确
|
||||
slog.Warn("login password not right",
|
||||
"username", user.Username)
|
||||
rsp.Body.Code = constant.PwdIncorrect
|
||||
}else{
|
||||
tt := time.Now()
|
||||
s := util.NewSession(user.UId, tt)
|
||||
|
||||
sessStr := s.String()
|
||||
|
||||
slog.Info("login",
|
||||
"username", user.Username,
|
||||
"session", sessStr)
|
||||
|
||||
//登录成功,写记录
|
||||
lh := &model.LoginHistory{UId: user.UId, CTime: tt, Ip: reqObj.Ip,
|
||||
Hardware: reqObj.Hardware, State: model.Login}
|
||||
db.MasterDB.Insert(lh)
|
||||
|
||||
ll := &model.LoginLast{}
|
||||
ok, _ := db.MasterDB.Table(ll).Where("uid=?", user.UId).Get(ll)
|
||||
if ok {
|
||||
ll.IsLogout = 0
|
||||
ll.Ip = reqObj.Ip
|
||||
ll.LoginTime = time.Now()
|
||||
ll.Session = sessStr
|
||||
ll.Hardware = reqObj.Hardware
|
||||
|
||||
_, err := db.MasterDB.ID(ll.Id).Cols(
|
||||
"is_logout", "ip", "login_time", "session", "hardware").Update(ll)
|
||||
if err != nil {
|
||||
slog.Error("update login_last table fail", "error", err)
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
ll = &model.LoginLast{UId: user.UId, LoginTime: tt,
|
||||
Ip: reqObj.Ip, Session: sessStr,
|
||||
Hardware: reqObj.Hardware, IsLogout: 0}
|
||||
db.MasterDB.Insert(ll)
|
||||
}
|
||||
|
||||
rspObj.Session = sessStr
|
||||
rspObj.Password = reqObj.Password
|
||||
rspObj.Username = reqObj.Username
|
||||
rspObj.UId = user.UId
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
net.ConnMgr.UserLogin(req.Conn, sessStr, ll.UId)
|
||||
}
|
||||
}else{
|
||||
//数据库出错
|
||||
slog.Warn("login username not found", "username", reqObj.Username)
|
||||
rsp.Body.Code = constant.UserNotExist
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this*Account) reLogin(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ReLoginReq{}
|
||||
rspObj := &proto.ReLoginRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
if reqObj.Session == ""{
|
||||
rsp.Body.Code = constant.SessionInvalid
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.Session = reqObj.Session
|
||||
|
||||
sess, err := util.ParseSession(reqObj.Session)
|
||||
if err != nil{
|
||||
rsp.Body.Code = constant.SessionInvalid
|
||||
}else{
|
||||
if sess.IsValid() {
|
||||
//数据库验证一下
|
||||
ll := &model.LoginLast{}
|
||||
db.MasterDB.Table(ll).Where("uid=?", sess.Id).Get(ll)
|
||||
|
||||
if ll.Session == reqObj.Session {
|
||||
if ll.Hardware == reqObj.Hardware {
|
||||
rsp.Body.Code = constant.OK
|
||||
net.ConnMgr.UserLogin(req.Conn, reqObj.Session, ll.UId)
|
||||
}else{
|
||||
rsp.Body.Code = constant.HardwareIncorrect
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.SessionInvalid
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.SessionInvalid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*Account) logout(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
reqObj := &proto.LogoutReq{}
|
||||
rspObj := &proto.LogoutRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.UId = reqObj.UId
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
slog.Info("logout", "uid", reqObj.UId)
|
||||
|
||||
tt := time.Now()
|
||||
//登出,写记录
|
||||
lh := &model.LoginHistory{UId: reqObj.UId, CTime: tt, State: model.Logout}
|
||||
db.MasterDB.Insert(lh)
|
||||
|
||||
ll := &model.LoginLast{}
|
||||
ok, _ := db.MasterDB.Table(ll).Where("uid=?", reqObj.UId).Get(ll)
|
||||
if ok {
|
||||
ll.IsLogout = 1
|
||||
ll.LogoutTime = time.Now()
|
||||
db.MasterDB.ID(ll.Id).Cols("is_logout", "logout_time").Update(ll)
|
||||
|
||||
}else{
|
||||
ll = &model.LoginLast{UId: reqObj.UId, LogoutTime: tt, IsLogout: 0}
|
||||
db.MasterDB.Insert(ll)
|
||||
}
|
||||
|
||||
net.ConnMgr.UserLogout(req.Conn)
|
||||
|
||||
}
|
||||
|
||||
func (this*Account) serverList(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ServerListReq{}
|
||||
rspObj := &proto.ServerListRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
s := proto.Server{Id: 1, Slg: "ws://127.0.0.1:8001", Chat: "ws://127.0.0.1:8002"}
|
||||
r := make([]proto.Server, 0)
|
||||
rspObj.Lists = append(r, s)
|
||||
|
||||
rsp.Body.Msg = rspObj
|
||||
}
|
||||
21
server/loginserver/init.go
Normal file
21
server/loginserver/init.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package loginserver
|
||||
|
||||
import (
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/loginserver/controller"
|
||||
)
|
||||
|
||||
|
||||
var MyRouter = &net.Router{}
|
||||
|
||||
func Init() {
|
||||
db.TestDB()
|
||||
//全部初始化完才注册路由,防止服务器还没启动就绪收到请求
|
||||
initRouter()
|
||||
}
|
||||
|
||||
func initRouter() {
|
||||
controller.DefaultAccount.InitRouter(MyRouter)
|
||||
}
|
||||
|
||||
39
server/loginserver/model/login.go
Normal file
39
server/loginserver/model/login.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
Login = iota
|
||||
Logout
|
||||
)
|
||||
|
||||
type LoginHistory struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
UId int `xorm:"uid"`
|
||||
CTime time.Time `xorm:"ctime"`
|
||||
Ip string `xorm:"ip"`
|
||||
State int8 `xorm:"state"`
|
||||
Hardware string `xorm:"hardware"`
|
||||
}
|
||||
|
||||
func (this *LoginHistory) TableName() string {
|
||||
return "tb_login_history"
|
||||
}
|
||||
|
||||
|
||||
type LoginLast struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
UId int `xorm:"uid"`
|
||||
LoginTime time.Time `xorm:"login_time"`
|
||||
LogoutTime time.Time `xorm:"logout_time"`
|
||||
Ip string `xorm:"ip"`
|
||||
Session string `xorm:"session"`
|
||||
IsLogout int8 `xorm:"is_logout"`
|
||||
Hardware string `xorm:"hardware"`
|
||||
}
|
||||
|
||||
func (this *LoginLast) TableName() string {
|
||||
return "tb_login_last"
|
||||
}
|
||||
19
server/loginserver/model/user.go
Normal file
19
server/loginserver/model/user.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type User struct {
|
||||
UId int `xorm:"uid pk autoincr"`
|
||||
Username string `xorm:"username" validate:"min=4,max=20,regexp=^[a-zA-Z0-9_]*$"`
|
||||
Passcode string `xorm:"passcode"`
|
||||
Passwd string `xorm:"passwd"`
|
||||
Hardware string `xorm:"hardware"`
|
||||
Status int `xorm:"status"`
|
||||
Ctime time.Time `xorm:"ctime"`
|
||||
Mtime time.Time `xorm:"mtime"`
|
||||
IsOnline bool `xorm:"-"`
|
||||
}
|
||||
|
||||
func (this *User) TableName() string {
|
||||
return "tb_user_info"
|
||||
}
|
||||
47
server/loginserver/proto/account.go
Normal file
47
server/loginserver/proto/account.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package proto
|
||||
|
||||
type LoginReq struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Ip string `json:"ip"`
|
||||
Hardware string `json:"hardware"`
|
||||
}
|
||||
|
||||
type LoginRsp struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Session string `json:"session"`
|
||||
UId int `json:"uid"`
|
||||
}
|
||||
|
||||
type ReLoginReq struct {
|
||||
Session string `json:"session"`
|
||||
Ip string `json:"ip"`
|
||||
Hardware string `json:"hardware"`
|
||||
}
|
||||
|
||||
type ReLoginRsp struct {
|
||||
Session string `json:"session"`
|
||||
}
|
||||
|
||||
type LogoutReq struct {
|
||||
UId int `json:"uid"`
|
||||
}
|
||||
|
||||
type LogoutRsp struct {
|
||||
UId int `json:"uid"`
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Id int `json:"id"`
|
||||
Slg string `json:"slg"`
|
||||
Chat string `json:"chat"`
|
||||
}
|
||||
|
||||
type ServerListReq struct {
|
||||
|
||||
}
|
||||
|
||||
type ServerListRsp struct {
|
||||
Lists []Server
|
||||
}
|
||||
12
server/slgserver/conn/push_sync.go
Normal file
12
server/slgserver/conn/push_sync.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package conn
|
||||
|
||||
type PushSync interface {
|
||||
IsCellView() bool //是否格子视野
|
||||
IsCanView(rid, x, y int)bool //是否能出现在视野
|
||||
BelongToRId() []int //属于的rid
|
||||
PushMsgName() string //推送名字
|
||||
Position() (int, int) //x, y
|
||||
TPosition() (int, int) //目标x, y
|
||||
ToProto() interface{} //转成proto
|
||||
Push() //推送
|
||||
}
|
||||
569
server/slgserver/controller/army.go
Normal file
569
server/slgserver/controller/army.go
Normal file
@@ -0,0 +1,569 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/logic"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"slgserver/server/slgserver/static_conf/general"
|
||||
"time"
|
||||
)
|
||||
|
||||
var DefaultArmy = Army{
|
||||
|
||||
}
|
||||
|
||||
type Army struct {
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (this*Army) InitRouter(r *net.Router) {
|
||||
g := r.Group("army").Use(middleware.ElapsedTime(), middleware.Log(),
|
||||
middleware.CheckLogin(), middleware.CheckRole())
|
||||
|
||||
g.AddRouter("myList", this.myList)
|
||||
g.AddRouter("myOne", this.myOne)
|
||||
g.AddRouter("dispose", this.dispose)
|
||||
g.AddRouter("conscript", this.conscript)
|
||||
g.AddRouter("assign", this.assign)
|
||||
|
||||
}
|
||||
|
||||
//我的军队列表
|
||||
func (this*Army) myList(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ArmyListReq{}
|
||||
rspObj := &proto.ArmyListRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
rspObj.CityId = reqObj.CityId
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
city,ok := mgr.RCMgr.Get(reqObj.CityId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.CityNotExist
|
||||
return
|
||||
}
|
||||
|
||||
if city.RId != role.RId {
|
||||
rsp.Body.Code = constant.CityNotMe
|
||||
return
|
||||
}
|
||||
|
||||
as, _ := mgr.AMgr.GetByCity(reqObj.CityId)
|
||||
rspObj.Armys = make([]proto.Army, len(as))
|
||||
for i, v := range as {
|
||||
rspObj.Armys[i] = v.ToProto().(proto.Army)
|
||||
}
|
||||
}
|
||||
|
||||
//我的某一个军队
|
||||
func (this*Army) myOne(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ArmyOneReq{}
|
||||
rspObj := &proto.ArmyOneRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
city, ok := mgr.RCMgr.Get(reqObj.CityId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.CityNotExist
|
||||
return
|
||||
}
|
||||
|
||||
if city.RId != role.RId {
|
||||
rsp.Body.Code = constant.CityNotMe
|
||||
return
|
||||
}
|
||||
|
||||
a, ok := mgr.AMgr.GetByCityOrder(reqObj.CityId, reqObj.Order)
|
||||
if ok {
|
||||
rspObj.Army = a.ToProto().(proto.Army)
|
||||
}else{
|
||||
rsp.Body.Code = constant.ArmyNotFound
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//配置武将
|
||||
func (this*Army) dispose(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
reqObj := &proto.DisposeReq{}
|
||||
rspObj := &proto.DisposeRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if reqObj.Order <= 0 || reqObj.Order > 5 || reqObj.Position < -1 || reqObj.Position >2 {
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
city, ok := mgr.RCMgr.Get(reqObj.CityId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.CityNotExist
|
||||
return
|
||||
}
|
||||
|
||||
if city.RId != role.RId {
|
||||
rsp.Body.Code = constant.CityNotMe
|
||||
return
|
||||
}
|
||||
|
||||
//校场每升一级一个队伍
|
||||
jc, ok := mgr.RFMgr.GetFacility(city.CityId, facility.JiaoChang)
|
||||
if ok == false || jc.GetLevel() < reqObj.Order {
|
||||
rsp.Body.Code = constant.ArmyNotEnough
|
||||
return
|
||||
}
|
||||
|
||||
newG, ok := mgr.GMgr.GetByGId(reqObj.GeneralId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GeneralNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if newG.RId != role.RId{
|
||||
rsp.Body.Code = constant.GeneralNotMe
|
||||
return
|
||||
}
|
||||
|
||||
army, err := mgr.AMgr.GetOrCreate(role.RId, reqObj.CityId, reqObj.Order)
|
||||
if err != nil{
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
if army.FromX != city.X || army.FromY != city.Y {
|
||||
rsp.Body.Code = constant.ArmyIsOutside
|
||||
return
|
||||
}
|
||||
|
||||
//下阵
|
||||
if reqObj.Position == -1{
|
||||
for pos, g := range army.Gens {
|
||||
if g != nil && g.Id == newG.Id{
|
||||
|
||||
//征兵中不能下阵
|
||||
if army.PositionCanModify(pos) == false{
|
||||
if army.Cmd == model.ArmyCmdConscript{
|
||||
rsp.Body.Code = constant.GeneralBusy
|
||||
}else{
|
||||
rsp.Body.Code = constant.ArmyBusy
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
army.GeneralArray[pos] = 0
|
||||
army.SoldierArray[pos] = 0
|
||||
army.Gens[pos] = nil
|
||||
army.SyncExecute()
|
||||
break
|
||||
}
|
||||
}
|
||||
newG.Order = 0
|
||||
newG.CityId = 0
|
||||
newG.SyncExecute()
|
||||
}else{
|
||||
|
||||
//征兵中不能下阵
|
||||
if army.PositionCanModify(reqObj.Position) == false{
|
||||
if army.Cmd == model.ArmyCmdConscript{
|
||||
rsp.Body.Code = constant.GeneralBusy
|
||||
}else{
|
||||
rsp.Body.Code = constant.ArmyBusy
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if newG.CityId != 0{
|
||||
rsp.Body.Code = constant.GeneralBusy
|
||||
return
|
||||
}
|
||||
|
||||
if mgr.AMgr.IsRepeat(role.RId, newG.CfgId) == false{
|
||||
rsp.Body.Code = constant.GeneralRepeat
|
||||
return
|
||||
}
|
||||
|
||||
//判断是否能配前锋
|
||||
tst, ok := mgr.RFMgr.GetFacility(city.CityId, facility.TongShuaiTing)
|
||||
if reqObj.Position == 2 && ( ok == false || tst.GetLevel() < reqObj.Order) {
|
||||
rsp.Body.Code = constant.TongShuaiNotEnough
|
||||
return
|
||||
}
|
||||
|
||||
//判断cost
|
||||
cost := general.General.Cost(newG.CfgId)
|
||||
for i, g := range army.Gens {
|
||||
if g == nil || i == reqObj.Position {
|
||||
continue
|
||||
}
|
||||
cost += general.General.Cost(g.CfgId)
|
||||
}
|
||||
|
||||
if mgr.GetCityCost(city.CityId) < cost{
|
||||
rsp.Body.Code = constant.CostNotEnough
|
||||
return
|
||||
}
|
||||
|
||||
oldG := army.Gens[reqObj.Position]
|
||||
if oldG != nil {
|
||||
//旧的下阵
|
||||
oldG.CityId = 0
|
||||
oldG.Order = 0
|
||||
oldG.SyncExecute()
|
||||
}
|
||||
|
||||
//新的上阵
|
||||
army.GeneralArray[reqObj.Position] = reqObj.GeneralId
|
||||
army.Gens[reqObj.Position] = newG
|
||||
army.SoldierArray[reqObj.Position] = 0
|
||||
|
||||
newG.Order = reqObj.Order
|
||||
newG.CityId = reqObj.CityId
|
||||
newG.SyncExecute()
|
||||
}
|
||||
|
||||
army.FromX = city.X
|
||||
army.FromY = city.Y
|
||||
army.SyncExecute()
|
||||
//队伍
|
||||
rspObj.Army = army.ToProto().(proto.Army)
|
||||
}
|
||||
|
||||
//征兵
|
||||
func (this*Army) conscript(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ConscriptReq{}
|
||||
rspObj := &proto.ConscriptRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
if reqObj.ArmyId <= 0 || len(reqObj.Cnts) != 3 ||
|
||||
reqObj.Cnts[0] < 0 || reqObj.Cnts[1] < 0 || reqObj.Cnts[2] < 0{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
army,ok := mgr.AMgr.Get(reqObj.ArmyId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.ArmyNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if role.RId != army.RId{
|
||||
rsp.Body.Code = constant.ArmyNotMe
|
||||
return
|
||||
}
|
||||
|
||||
//判断该位置是否能征兵
|
||||
for pos, cnt := range reqObj.Cnts {
|
||||
if cnt > 0{
|
||||
if army.Gens[pos] == nil{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
if army.PositionCanModify(pos) == false{
|
||||
rsp.Body.Code = constant.GeneralBusy
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lv := mgr.RFMgr.GetFacilityLv(army.CityId, facility.MBS)
|
||||
if lv <= 0{
|
||||
rsp.Body.Code = constant.BuildMBSNotFound
|
||||
return
|
||||
}
|
||||
|
||||
//判断是否超过上限
|
||||
for i, g := range army.Gens {
|
||||
if g == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
l, e := general.GenBasic.GetLevel(g.Level)
|
||||
add := mgr.RFMgr.GetAdditions(army.CityId, facility.TypeSoldierLimit)
|
||||
if e == nil{
|
||||
if l.Soldiers + add[0] < reqObj.Cnts[i]+army.SoldierArray[i]{
|
||||
rsp.Body.Code = constant.OutArmyLimit
|
||||
return
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//开始征兵
|
||||
total := 0
|
||||
for _, n := range reqObj.Cnts {
|
||||
total += n
|
||||
}
|
||||
|
||||
conscript := static_conf.Basic.ConScript
|
||||
needWood := total*conscript.CostWood
|
||||
needGrain := total*conscript.CostGrain
|
||||
needIron := total*conscript.CostIron
|
||||
needStone := total*conscript.CostStone
|
||||
needGold := total*conscript.CostGold
|
||||
|
||||
nr := facility.NeedRes{Grain: needGrain, Wood: needWood,
|
||||
Gold: needGold, Iron: needIron, Decree: 0,
|
||||
Stone: needStone}
|
||||
|
||||
if code := mgr.RResMgr.TryUseNeed(army.RId, nr); code == constant.OK {
|
||||
curTime := time.Now().Unix()
|
||||
for i, _ := range army.SoldierArray {
|
||||
if reqObj.Cnts[i] > 0{
|
||||
army.ConscriptCntArray[i] = reqObj.Cnts[i]
|
||||
army.ConscriptTimeArray[i] = int64(reqObj.Cnts[i]*conscript.CostTime) + curTime - 2
|
||||
}
|
||||
}
|
||||
|
||||
army.Cmd = model.ArmyCmdConscript
|
||||
army.SyncExecute()
|
||||
|
||||
//队伍
|
||||
rspObj.Army = army.ToProto().(proto.Army)
|
||||
|
||||
//资源
|
||||
if rRes, ok := mgr.RResMgr.Get(role.RId); ok {
|
||||
rspObj.RoleRes = rRes.ToProto().(proto.RoleRes)
|
||||
}
|
||||
rsp.Body.Code = constant.OK
|
||||
}else{
|
||||
rsp.Body.Code = constant.ResNotEnough
|
||||
}
|
||||
}
|
||||
|
||||
//派遣队伍
|
||||
func (this*Army) assign(req *net.WsMsgReq, rsp *net.WsMsgRsp){
|
||||
reqObj := &proto.AssignArmyReq{}
|
||||
rspObj := &proto.AssignArmyRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
army,ok := mgr.AMgr.Get(reqObj.ArmyId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.ArmyNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if role.RId != army.RId{
|
||||
rsp.Body.Code = constant.ArmyNotMe
|
||||
return
|
||||
}
|
||||
|
||||
if reqObj.Cmd == model.ArmyCmdBack{
|
||||
rsp.Body.Code = this.__back__(army)
|
||||
}else if reqObj.Cmd == model.ArmyCmdAttack {
|
||||
rsp.Body.Code = this.__attack__(reqObj, army, role)
|
||||
}else if reqObj.Cmd == model.ArmyCmdDefend {
|
||||
rsp.Body.Code = this.__defend__(reqObj, army, role)
|
||||
}else if reqObj.Cmd == model.ArmyCmdReclamation {
|
||||
rsp.Body.Code = this.__reclamation__(reqObj, army, role)
|
||||
}else if reqObj.Cmd == model.ArmyCmdTransfer {
|
||||
rsp.Body.Code = this.__transfer__(reqObj, army, role)
|
||||
}
|
||||
|
||||
rspObj.Army = army.ToProto().(proto.Army)
|
||||
}
|
||||
|
||||
|
||||
func (this*Army) __pre__(reqObj *proto.AssignArmyReq, army* model.Army, role *model.Role) int{
|
||||
|
||||
if reqObj.X < 0 || reqObj.X >= global.MapWith ||
|
||||
reqObj.Y < 0 || reqObj.Y >= global.MapHeight {
|
||||
return constant.InvalidParam
|
||||
}
|
||||
|
||||
if army.IsCanOutWar() == false{
|
||||
if army.Cmd != model.ArmyCmdIdle{
|
||||
return constant.ArmyBusy
|
||||
}else{
|
||||
return constant.ArmyNotMain
|
||||
}
|
||||
}
|
||||
|
||||
if army.IsIdle() == false {
|
||||
return constant.ArmyBusy
|
||||
}
|
||||
|
||||
//判断该地是否是能攻击类型
|
||||
cfg, ok := mgr.NMMgr.PositionBuild(reqObj.X, reqObj.Y)
|
||||
if ok == false || cfg.Type == 0 {
|
||||
return constant.InvalidParam
|
||||
}
|
||||
|
||||
if logic.IsCanArrive(reqObj.X, reqObj.Y, role.RId) == false{
|
||||
return constant.UnReachable
|
||||
}
|
||||
|
||||
return constant.OK
|
||||
}
|
||||
|
||||
func (this*Army) __after__(reqObj *proto.AssignArmyReq, army* model.Army) int{
|
||||
//最后才消耗体力
|
||||
cost := static_conf.Basic.General.CostPhysicalPower
|
||||
ok := mgr.GMgr.PhysicalPowerIsEnough(army, cost)
|
||||
if ok == false{
|
||||
return constant.PhysicalPowerNotEnough
|
||||
}
|
||||
|
||||
if reqObj.Cmd == model.ArmyCmdReclamation || reqObj.Cmd == model.ArmyCmdTransfer {
|
||||
cost := static_conf.Basic.General.ReclamationCost
|
||||
if mgr.RResMgr.DecreeIsEnough(army.RId, cost) == false{
|
||||
return constant.DecreeNotEnough
|
||||
}else{
|
||||
mgr.RResMgr.TryUseDecree(army.RId, cost)
|
||||
}
|
||||
}
|
||||
|
||||
mgr.GMgr.TryUsePhysicalPower(army, cost)
|
||||
|
||||
army.ToX = reqObj.X
|
||||
army.ToY = reqObj.Y
|
||||
army.Cmd = reqObj.Cmd
|
||||
army.State = model.ArmyRunning
|
||||
|
||||
//speed := mgr.AMgr.GetSpeed(army)
|
||||
//t := mgr.TravelTime(speed, army.FromX, army.FromY, army.ToX, army.ToY)
|
||||
army.Start = time.Now()
|
||||
//army.End = time.Now().Add(time.Duration(t) * time.Millisecond)
|
||||
army.End = time.Now().Add(40*time.Second)
|
||||
logic.ArmyLogic.PushAction(army)
|
||||
return constant.OK
|
||||
}
|
||||
|
||||
//返回
|
||||
func (this*Army) __back__(army* model.Army) int{
|
||||
if army.Cmd == model.ArmyCmdAttack ||
|
||||
army.Cmd == model.ArmyCmdDefend ||
|
||||
army.Cmd == model.ArmyCmdReclamation {
|
||||
logic.ArmyLogic.ArmyBack(army)
|
||||
}else if army.IsIdle(){
|
||||
city, ok := mgr.RCMgr.Get(army.CityId)
|
||||
if ok {
|
||||
if city.X != army.FromX || city.Y != army.FromY{
|
||||
logic.ArmyLogic.ArmyBack(army)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return constant.OK
|
||||
}
|
||||
|
||||
//攻击
|
||||
func (this*Army) __attack__(reqObj *proto.AssignArmyReq, army* model.Army, role *model.Role) int{
|
||||
|
||||
code := this.__pre__(reqObj, army, role)
|
||||
if code != constant.OK {
|
||||
return code
|
||||
}
|
||||
|
||||
if logic.IsCanArrive(reqObj.X, reqObj.Y, role.RId) == false{
|
||||
return constant.UnReachable
|
||||
}
|
||||
|
||||
//免战
|
||||
if logic.IsWarFree(reqObj.X, reqObj.Y){
|
||||
return constant.BuildWarFree
|
||||
}
|
||||
|
||||
if logic.IsCanDefend(reqObj.X, reqObj.Y, role.RId) == true {
|
||||
return constant.BuildCanNotAttack
|
||||
}
|
||||
|
||||
return this.__after__(reqObj, army)
|
||||
}
|
||||
|
||||
//驻守
|
||||
func (this*Army) __defend__(reqObj *proto.AssignArmyReq, army* model.Army, role *model.Role) int{
|
||||
|
||||
code := this.__pre__(reqObj, army, role)
|
||||
if code != constant.OK {
|
||||
return code
|
||||
}
|
||||
|
||||
if logic.IsCanDefend(reqObj.X, reqObj.Y, role.RId) == false {
|
||||
return constant.BuildCanNotDefend
|
||||
}
|
||||
|
||||
return this.__after__(reqObj, army)
|
||||
}
|
||||
|
||||
func (this*Army) __reclamation__(reqObj *proto.AssignArmyReq, army* model.Army, role *model.Role) int{
|
||||
|
||||
code := this.__pre__(reqObj, army, role)
|
||||
if code != constant.OK {
|
||||
return code
|
||||
}
|
||||
|
||||
if mgr.RBMgr.BuildIsRId(reqObj.X, reqObj.Y, role.RId) == false {
|
||||
return constant.BuildNotMe
|
||||
}
|
||||
|
||||
return this.__after__(reqObj, army)
|
||||
}
|
||||
|
||||
func (this*Army) __transfer__(reqObj *proto.AssignArmyReq, army* model.Army, role *model.Role) int{
|
||||
|
||||
code := this.__pre__(reqObj, army, role)
|
||||
if code != constant.OK {
|
||||
return code
|
||||
}
|
||||
|
||||
if army.FromX == reqObj.X && army.FromY == reqObj.Y{
|
||||
return constant.CanNotTransfer
|
||||
}
|
||||
|
||||
if mgr.RBMgr.BuildIsRId(reqObj.X, reqObj.Y, role.RId) == false {
|
||||
return constant.BuildNotMe
|
||||
}
|
||||
|
||||
b, ok := mgr.RBMgr.PositionBuild(reqObj.X, reqObj.Y)
|
||||
if ok == false {
|
||||
return constant.BuildNotMe
|
||||
}
|
||||
|
||||
if b.Level <= 0 || b.IsHasTransferAuth() == false {
|
||||
return constant.CanNotTransfer
|
||||
}
|
||||
|
||||
cnt := 0
|
||||
if b.IsRoleFortress() {
|
||||
cnt = static_conf.MapBCConf.GetHoldArmyCnt(b.Type, b.Level)
|
||||
}else{
|
||||
cnt = 5
|
||||
}
|
||||
|
||||
if cnt > mgr.AMgr.BelongPosArmyCnt(b.RId, b.X, b.Y) {
|
||||
return this.__after__(reqObj, army)
|
||||
}else{
|
||||
return constant.HoldIsFull
|
||||
}
|
||||
|
||||
}
|
||||
109
server/slgserver/controller/city.go
Normal file
109
server/slgserver/controller/city.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
)
|
||||
|
||||
var DefaultCity = City{
|
||||
|
||||
}
|
||||
type City struct {
|
||||
|
||||
}
|
||||
|
||||
func (this*City) InitRouter(r *net.Router) {
|
||||
g := r.Group("city").Use(middleware.ElapsedTime(), middleware.Log(),
|
||||
middleware.CheckLogin(), middleware.CheckRole())
|
||||
|
||||
g.AddRouter("facilities", this.facilities)
|
||||
g.AddRouter("upFacility", this.upFacility)
|
||||
|
||||
}
|
||||
|
||||
func (this*City) facilities(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.FacilitiesReq{}
|
||||
rspObj := &proto.FacilitiesRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.CityId = reqObj.CityId
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
city, ok := mgr.RCMgr.Get(reqObj.CityId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.CityNotExist
|
||||
return
|
||||
}
|
||||
|
||||
role := r.(*model.Role)
|
||||
if city.RId != role.RId {
|
||||
rsp.Body.Code = constant.CityNotMe
|
||||
return
|
||||
}
|
||||
|
||||
f, ok := mgr.RFMgr.Get(reqObj.CityId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.CityNotExist
|
||||
return
|
||||
}
|
||||
|
||||
t := f.Facility()
|
||||
|
||||
rspObj.Facilities = make([]proto.Facility, len(t))
|
||||
for i, v := range t {
|
||||
rspObj.Facilities[i].Name = v.Name
|
||||
rspObj.Facilities[i].Level = v.GetLevel()
|
||||
rspObj.Facilities[i].Type = v.Type
|
||||
rspObj.Facilities[i].UpTime = v.UpTime
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//升级需要耗费时间,为了减少定时任务,升级这里做成被动触发产生,不做定时任务
|
||||
func (this*City) upFacility(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.UpFacilityReq{}
|
||||
rspObj := &proto.UpFacilityRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.CityId = reqObj.CityId
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
city, ok := mgr.RCMgr.Get(reqObj.CityId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.CityNotExist
|
||||
return
|
||||
}
|
||||
|
||||
role := r.(*model.Role)
|
||||
if city.RId != role.RId {
|
||||
rsp.Body.Code = constant.CityNotMe
|
||||
return
|
||||
}
|
||||
|
||||
_, ok = mgr.RFMgr.Get(reqObj.CityId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.CityNotExist
|
||||
return
|
||||
}
|
||||
|
||||
out, errCode := mgr.RFMgr.UpFacility(role.RId ,reqObj.CityId, reqObj.FType)
|
||||
rsp.Body.Code = errCode
|
||||
if errCode == constant.OK{
|
||||
rspObj.Facility.Level = out.GetLevel()
|
||||
rspObj.Facility.Type = out.Type
|
||||
rspObj.Facility.Name = out.Name
|
||||
rspObj.Facility.UpTime = out.UpTime
|
||||
|
||||
if roleRes, ok:= mgr.RResMgr.Get(role.RId); ok {
|
||||
rspObj.RoleRes = roleRes.ToProto().(proto.RoleRes)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
688
server/slgserver/controller/coalition.go
Normal file
688
server/slgserver/controller/coalition.go
Normal file
@@ -0,0 +1,688 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/logic"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"time"
|
||||
)
|
||||
|
||||
var DefaultCoalition= coalition{
|
||||
|
||||
}
|
||||
|
||||
type coalition struct {
|
||||
|
||||
}
|
||||
|
||||
func (this *coalition) InitRouter(r *net.Router) {
|
||||
g := r.Group("union").Use(middleware.ElapsedTime(), middleware.Log(),
|
||||
middleware.CheckLogin(), middleware.CheckRole())
|
||||
|
||||
g.AddRouter("create", this.create)
|
||||
g.AddRouter("list", this.list)
|
||||
g.AddRouter("join", this.join)
|
||||
g.AddRouter("verify", this.verify)
|
||||
g.AddRouter("member", this.member)
|
||||
g.AddRouter("applyList", this.applyList)
|
||||
g.AddRouter("exit", this.exit)
|
||||
g.AddRouter("dismiss", this.dismiss)
|
||||
g.AddRouter("notice", this.notice)
|
||||
g.AddRouter("modNotice", this.modNotice)
|
||||
g.AddRouter("kick", this.kick)
|
||||
g.AddRouter("appoint", this.appoint)
|
||||
g.AddRouter("abdicate", this.abdicate)
|
||||
g.AddRouter("info", this.info)
|
||||
g.AddRouter("log", this.log)
|
||||
|
||||
}
|
||||
|
||||
//创建联盟
|
||||
func (this *coalition) create(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.CreateReq{}
|
||||
rspObj := &proto.CreateRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
rspObj.Name = reqObj.Name
|
||||
|
||||
has := mgr.RAttrMgr.IsHasUnion(role.RId)
|
||||
if has {
|
||||
rsp.Body.Code = constant.UnionAlreadyHas
|
||||
return
|
||||
}
|
||||
|
||||
c, ok := mgr.UnionMgr.Create(reqObj.Name, role.RId)
|
||||
if ok {
|
||||
rspObj.Id = c.Id
|
||||
logic.Union.MemberEnter(role.RId, c.Id)
|
||||
model.NewCreate(role.NickName, c.Id, role.RId)
|
||||
}else{
|
||||
rsp.Body.Code = constant.UnionCreateError
|
||||
}
|
||||
}
|
||||
|
||||
//联盟列表
|
||||
func (this *coalition) list(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ListReq{}
|
||||
rspObj := &proto.ListRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
l := mgr.UnionMgr.List()
|
||||
rspObj.List = make([]proto.Union, len(l))
|
||||
for i, u := range l {
|
||||
rspObj.List[i] = u.ToProto().(proto.Union)
|
||||
main := make([]proto.Major, 0)
|
||||
if r, ok := mgr.RMgr.Get(u.Chairman); ok {
|
||||
m := proto.Major{Name: r.NickName, RId: r.RId, Title: proto.UnionChairman}
|
||||
main = append(main, m)
|
||||
}
|
||||
|
||||
if r, ok := mgr.RMgr.Get(u.ViceChairman); ok {
|
||||
m := proto.Major{Name: r.NickName, RId: r.RId, Title: proto.UnionViceChairman}
|
||||
main = append(main, m)
|
||||
}
|
||||
rspObj.List[i].Major = main
|
||||
}
|
||||
}
|
||||
|
||||
//加入
|
||||
func (this *coalition) join(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.JoinReq{}
|
||||
rspObj := &proto.JoinRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
has := mgr.RAttrMgr.IsHasUnion(role.RId)
|
||||
if has {
|
||||
rsp.Body.Code = constant.UnionAlreadyHas
|
||||
return
|
||||
}
|
||||
|
||||
u, ok := mgr.UnionMgr.Get(reqObj.Id)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if len(u.MemberArray) >= static_conf.Basic.Union.MemberLimit{
|
||||
rsp.Body.Code = constant.PeopleIsFull
|
||||
return
|
||||
}
|
||||
|
||||
//判断当前是否已经有申请
|
||||
has, _ = db.MasterDB.Table(model.CoalitionApply{}).Where(
|
||||
"union_id=? and state=? and rid=?",
|
||||
reqObj.Id, proto.UnionUntreated, role.RId).Get(&model.CoalitionApply{})
|
||||
if has {
|
||||
rsp.Body.Code = constant.HasApply
|
||||
return
|
||||
}
|
||||
|
||||
//写入申请列表
|
||||
apply := &model.CoalitionApply{
|
||||
RId: role.RId,
|
||||
UnionId: reqObj.Id,
|
||||
Ctime: time.Now(),
|
||||
State: proto.UnionUntreated}
|
||||
|
||||
_, err := db.MasterDB.InsertOne(apply)
|
||||
if err != nil{
|
||||
rsp.Body.Code = constant.DBError
|
||||
slog.Warn("db error", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
//推送主、副盟主
|
||||
apply.SyncExecute()
|
||||
}
|
||||
|
||||
//审核
|
||||
func (this *coalition) verify(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
reqObj := &proto.VerifyReq{}
|
||||
rspObj := &proto.VerifyRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.Id = reqObj.Id
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
|
||||
apply := &model.CoalitionApply{}
|
||||
ok, err := db.MasterDB.Table(model.CoalitionApply{}).Where(
|
||||
"id=? and state=?", reqObj.Id, proto.UnionUntreated).Get(apply)
|
||||
if ok && err == nil{
|
||||
targetRole, ok := mgr.RMgr.Get(apply.RId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}
|
||||
|
||||
if u, ok := mgr.UnionMgr.Get(apply.UnionId); ok {
|
||||
|
||||
if u.Chairman != role.RId && u.ViceChairman != role.RId {
|
||||
rsp.Body.Code = constant.PermissionDenied
|
||||
return
|
||||
}
|
||||
|
||||
if len(u.MemberArray) >= static_conf.Basic.Union.MemberLimit{
|
||||
rsp.Body.Code = constant.PeopleIsFull
|
||||
return
|
||||
}
|
||||
|
||||
if ok := mgr.RAttrMgr.IsHasUnion(apply.RId); ok {
|
||||
rsp.Body.Code = constant.UnionAlreadyHas
|
||||
}else{
|
||||
if reqObj.Decide == proto.UnionAdopt {
|
||||
//同意
|
||||
c, ok := mgr.UnionMgr.Get(apply.UnionId)
|
||||
if ok {
|
||||
c.MemberArray = append(c.MemberArray, apply.RId)
|
||||
logic.Union.MemberEnter(apply.RId, apply.UnionId)
|
||||
c.SyncExecute()
|
||||
model.NewJoin(targetRole.NickName, apply.UnionId, role.RId, apply.RId)
|
||||
}
|
||||
}
|
||||
}
|
||||
apply.State = reqObj.Decide
|
||||
db.MasterDB.Table(apply).ID(apply.Id).Cols("state").Update(apply)
|
||||
}else{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
}else{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//成员列表
|
||||
func (this *coalition) member(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.MemberReq{}
|
||||
rspObj := &proto.MemberRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.Id = reqObj.Id
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
union, ok := mgr.UnionMgr.Get(reqObj.Id)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
rspObj.Members = make([]proto.Member, 0)
|
||||
for _, rid := range union.MemberArray {
|
||||
if role, ok := mgr.RMgr.Get(rid); ok {
|
||||
m := proto.Member{RId: role.RId, Name: role.NickName }
|
||||
if main, ok := mgr.RCMgr.GetMainCity(role.RId); ok {
|
||||
m.X = main.X
|
||||
m.Y = main.Y
|
||||
}
|
||||
|
||||
if rid == union.Chairman {
|
||||
m.Title = proto.UnionChairman
|
||||
}else if rid == union.ViceChairman {
|
||||
m.Title = proto.UnionViceChairman
|
||||
}else {
|
||||
m.Title = proto.UnionCommon
|
||||
}
|
||||
rspObj.Members = append(rspObj.Members, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//申请列表
|
||||
func (this *coalition) applyList(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ApplyReq{}
|
||||
rspObj := &proto.ApplyRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
u, ok := mgr.UnionMgr.Get(reqObj.Id)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if u.Chairman != role.RId && u.ViceChairman != role.RId {
|
||||
rspObj.Applys = make([]proto.ApplyItem, 0)
|
||||
return
|
||||
}
|
||||
|
||||
applys := make([]*model.CoalitionApply, 0)
|
||||
err := db.MasterDB.Table(model.CoalitionApply{}).Where(
|
||||
"union_id=? and state=?", reqObj.Id, 0).Find(&applys)
|
||||
if err != nil{
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
rspObj.Id = reqObj.Id
|
||||
rspObj.Applys = make([]proto.ApplyItem, 0)
|
||||
for _, apply := range applys {
|
||||
if r, ok := mgr.RMgr.Get(apply.RId);ok{
|
||||
a := proto.ApplyItem{Id: apply.Id, RId: apply.RId, NickName: r.NickName}
|
||||
rspObj.Applys = append(rspObj.Applys, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//退出
|
||||
func (this *coalition) exit(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ExitReq{}
|
||||
rspObj := &proto.ExitRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if ok := mgr.RAttrMgr.IsHasUnion(role.RId); ok == false {
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
attribute, _ := mgr.RAttrMgr.Get(role.RId)
|
||||
u, ok := mgr.UnionMgr.Get(attribute.UnionId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
//盟主不能退出
|
||||
if u.Chairman == role.RId {
|
||||
rsp.Body.Code = constant.UnionNotAllowExit
|
||||
return
|
||||
}
|
||||
|
||||
for i, rid := range u.MemberArray {
|
||||
if rid == role.RId{
|
||||
u.MemberArray = append(u.MemberArray[:i], u.MemberArray[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
if u.ViceChairman == role.RId{
|
||||
u.ViceChairman = 0
|
||||
}
|
||||
|
||||
logic.Union.MemberExit(role.RId)
|
||||
u.SyncExecute()
|
||||
model.NewExit(role.NickName, u.Id, role.RId)
|
||||
|
||||
}
|
||||
|
||||
|
||||
//解散
|
||||
func (this *coalition) dismiss(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.DismissReq{}
|
||||
rspObj := &proto.DismissRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if ok := mgr.RAttrMgr.IsHasUnion(role.RId); ok == false {
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
attribute, _ := mgr.RAttrMgr.Get(role.RId)
|
||||
u, ok := mgr.UnionMgr.Get(attribute.UnionId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
//盟主才能解散
|
||||
if u.Chairman != role.RId {
|
||||
rsp.Body.Code = constant.PermissionDenied
|
||||
return
|
||||
}
|
||||
unionId := attribute.UnionId
|
||||
logic.Union.Dismiss(unionId)
|
||||
|
||||
model.NewDismiss(role.NickName, unionId, role.RId)
|
||||
}
|
||||
|
||||
//公告
|
||||
func (this *coalition) notice(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.NoticeReq{}
|
||||
rspObj := &proto.NoticeRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
u, ok := mgr.UnionMgr.Get(reqObj.Id)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
rspObj.Text = u.Notice
|
||||
}
|
||||
|
||||
//修改公告
|
||||
func (this *coalition) modNotice(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ModNoticeReq{}
|
||||
rspObj := &proto.ModNoticeRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if len(reqObj.Text) > 200 {
|
||||
rsp.Body.Code = constant.ContentTooLong
|
||||
return
|
||||
}
|
||||
|
||||
if ok := mgr.RAttrMgr.IsHasUnion(role.RId); ok == false {
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
attribute, _ := mgr.RAttrMgr.Get(role.RId)
|
||||
u, ok := mgr.UnionMgr.Get(attribute.UnionId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if u.Chairman != role.RId && u.ViceChairman != role.RId {
|
||||
rsp.Body.Code = constant.PermissionDenied
|
||||
return
|
||||
}
|
||||
|
||||
rspObj.Text = reqObj.Text
|
||||
rspObj.Id = u.Id
|
||||
u.Notice = reqObj.Text
|
||||
u.SyncExecute()
|
||||
|
||||
model.NewModNotice(role.NickName, u.Id, role.RId)
|
||||
}
|
||||
|
||||
//踢人
|
||||
func (this *coalition) kick(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.KickReq{}
|
||||
rspObj := &proto.KickRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.RId = reqObj.RId
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if ok := mgr.RAttrMgr.IsHasUnion(role.RId); ok == false {
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
opAr, _ := mgr.RAttrMgr.Get(role.RId)
|
||||
u, ok := mgr.UnionMgr.Get(opAr.UnionId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if u.Chairman != role.RId && u.ViceChairman != role.RId {
|
||||
rsp.Body.Code = constant.PermissionDenied
|
||||
return
|
||||
}
|
||||
|
||||
if role.RId == reqObj.RId {
|
||||
rsp.Body.Code = constant.PermissionDenied
|
||||
return
|
||||
}
|
||||
|
||||
targetRole, ok := mgr.RMgr.Get(reqObj.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}
|
||||
|
||||
target, ok := mgr.RAttrMgr.Get(reqObj.RId)
|
||||
if ok {
|
||||
if target.UnionId == u.Id{
|
||||
for i, rid := range u.MemberArray {
|
||||
if rid == reqObj.RId{
|
||||
u.MemberArray = append(u.MemberArray[:i], u.MemberArray[i+1:]...)
|
||||
}
|
||||
}
|
||||
if u.ViceChairman == reqObj.RId{
|
||||
u.ViceChairman = 0
|
||||
}
|
||||
logic.Union.MemberExit(reqObj.RId)
|
||||
target.UnionId = 0
|
||||
u.SyncExecute()
|
||||
|
||||
model.NewKick(role.NickName, targetRole.NickName, u.Id, role.RId, target.RId)
|
||||
}else{
|
||||
rsp.Body.Code = constant.NotBelongUnion
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.NotBelongUnion
|
||||
}
|
||||
}
|
||||
|
||||
//任命
|
||||
func (this *coalition) appoint(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.AppointReq{}
|
||||
rspObj := &proto.AppointRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.RId = reqObj.RId
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if ok := mgr.RAttrMgr.IsHasUnion(role.RId); ok == false {
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
opAr, _ := mgr.RAttrMgr.Get(role.RId)
|
||||
u, ok := mgr.UnionMgr.Get(opAr.UnionId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if u.Chairman != role.RId {
|
||||
rsp.Body.Code = constant.PermissionDenied
|
||||
return
|
||||
}
|
||||
|
||||
targetRole, ok := mgr.RMgr.Get(reqObj.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}
|
||||
|
||||
target, ok := mgr.RAttrMgr.Get(reqObj.RId)
|
||||
if ok {
|
||||
if target.UnionId == u.Id{
|
||||
if reqObj.Title == proto.UnionViceChairman {
|
||||
u.ViceChairman = reqObj.RId
|
||||
rspObj.Title = reqObj.Title
|
||||
u.SyncExecute()
|
||||
model.NewAppoint(role.NickName, targetRole.NickName, u.Id, role.RId, targetRole.RId, reqObj.Title)
|
||||
}else if reqObj.Title == proto.UnionCommon {
|
||||
if u.ViceChairman == reqObj.RId{
|
||||
u.ViceChairman = 0
|
||||
}
|
||||
rspObj.Title = reqObj.Title
|
||||
model.NewAppoint(role.NickName, targetRole.NickName, u.Id, role.RId, targetRole.RId, reqObj.Title)
|
||||
}else{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.NotBelongUnion
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.NotBelongUnion
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//禅让
|
||||
func (this *coalition) abdicate(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.AbdicateReq{}
|
||||
rspObj := &proto.AbdicateRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if ok := mgr.RAttrMgr.IsHasUnion(role.RId); ok == false {
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
opAr, _ := mgr.RAttrMgr.Get(role.RId)
|
||||
u, ok := mgr.UnionMgr.Get(opAr.UnionId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
targetRole, ok := mgr.RMgr.Get(reqObj.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}
|
||||
|
||||
if u.Chairman != role.RId && u.ViceChairman != role.RId {
|
||||
rsp.Body.Code = constant.PermissionDenied
|
||||
return
|
||||
}
|
||||
|
||||
target, ok := mgr.RAttrMgr.Get(reqObj.RId)
|
||||
if ok {
|
||||
if target.UnionId == u.Id{
|
||||
if role.RId == u.Chairman{
|
||||
u.Chairman = reqObj.RId
|
||||
if u.ViceChairman == reqObj.RId{
|
||||
u.ViceChairman = 0
|
||||
}
|
||||
u.SyncExecute()
|
||||
|
||||
model.NewAbdicate(role.NickName, targetRole.NickName, u.Id,
|
||||
role.RId, targetRole.RId, proto.UnionChairman)
|
||||
}else if role.RId == u.ViceChairman {
|
||||
u.ViceChairman = reqObj.RId
|
||||
u.SyncExecute()
|
||||
|
||||
model.NewAbdicate(role.NickName, targetRole.NickName, u.Id,
|
||||
role.RId, targetRole.RId, proto.UnionViceChairman)
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.NotBelongUnion
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.NotBelongUnion
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//联盟信息
|
||||
func (this *coalition) info(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.InfoReq{}
|
||||
rspObj := &proto.InfoRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.Id = reqObj.Id
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
u, ok := mgr.UnionMgr.Get(reqObj.Id)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
}else{
|
||||
rspObj.Info = u.ToProto().(proto.Union)
|
||||
main := make([]proto.Major, 0)
|
||||
if r, ok := mgr.RMgr.Get(u.Chairman); ok {
|
||||
m := proto.Major{Name: r.NickName, RId: r.RId, Title: proto.UnionChairman}
|
||||
main = append(main, m)
|
||||
}
|
||||
|
||||
if r, ok := mgr.RMgr.Get(u.ViceChairman); ok {
|
||||
m := proto.Major{Name: r.NickName, RId: r.RId, Title: proto.UnionViceChairman}
|
||||
main = append(main, m)
|
||||
}
|
||||
rspObj.Info.Major = main
|
||||
}
|
||||
}
|
||||
|
||||
//联盟日志
|
||||
func (this *coalition) log(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.LogReq{}
|
||||
rspObj := &proto.LogRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rspObj.Logs = make([]proto.UnionLog, 0)
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
opAr, _ := mgr.RAttrMgr.Get(role.RId)
|
||||
u, ok := mgr.UnionMgr.Get(opAr.UnionId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.UnionNotFound
|
||||
return
|
||||
}
|
||||
|
||||
//开始查询日志
|
||||
logs := make([]*model.CoalitionLog, 0)
|
||||
err := db.MasterDB.Table(model.CoalitionLog{}).Where(
|
||||
"union_id=?", u.Id).Desc("ctime").Find(&logs)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
|
||||
for _, cLog := range logs {
|
||||
rspObj.Logs = append(rspObj.Logs, cLog.ToProto().(proto.UnionLog))
|
||||
}
|
||||
}
|
||||
385
server/slgserver/controller/general.go
Normal file
385
server/slgserver/controller/general.go
Normal file
@@ -0,0 +1,385 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/skill"
|
||||
)
|
||||
|
||||
var DefaultGeneral = General{
|
||||
|
||||
}
|
||||
|
||||
type General struct {
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (this*General) InitRouter(r *net.Router) {
|
||||
g := r.Group("general").Use(middleware.ElapsedTime(), middleware.Log(),
|
||||
middleware.CheckLogin(), middleware.CheckRole())
|
||||
|
||||
g.AddRouter("myGenerals", this.myGenerals)
|
||||
g.AddRouter("drawGeneral", this.drawGenerals)
|
||||
g.AddRouter("composeGeneral", this.composeGeneral)
|
||||
g.AddRouter("addPrGeneral", this.addPrGeneral)
|
||||
g.AddRouter("convert", this.convert)
|
||||
g.AddRouter("upSkill", this.upSkill)
|
||||
g.AddRouter("downSkill", this.downSkill)
|
||||
g.AddRouter("lvSkill", this.lvSkill)
|
||||
|
||||
}
|
||||
|
||||
func (this*General) myGenerals(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.MyGeneralReq{}
|
||||
rspObj := &proto.MyGeneralRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
gs, ok := mgr.GMgr.GetOrCreateByRId(role.RId)
|
||||
if ok {
|
||||
rsp.Body.Code = constant.OK
|
||||
rspObj.Generals = make([]proto.General, 0)
|
||||
for _, v := range gs {
|
||||
rspObj.Generals = append(rspObj.Generals, v.ToProto().(proto.General))
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.DBError
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*General) drawGenerals(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.DrawGeneralReq{}
|
||||
rspObj := &proto.DrawGeneralRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
cost := static_conf.Basic.General.DrawGeneralCost * reqObj.DrawTimes
|
||||
ok := mgr.RResMgr.GoldIsEnough(role.RId,cost)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GoldNotEnough
|
||||
return
|
||||
}
|
||||
|
||||
limit := static_conf.Basic.General.Limit
|
||||
cnt := mgr.GMgr.Count(role.RId)
|
||||
if cnt + reqObj.DrawTimes > limit{
|
||||
rsp.Body.Code = constant.OutGeneralLimit
|
||||
return
|
||||
}
|
||||
|
||||
gs, ok := mgr.GMgr.RandCreateGeneral(role.RId,reqObj.DrawTimes)
|
||||
|
||||
if ok {
|
||||
mgr.RResMgr.TryUseGold(role.RId, cost)
|
||||
rsp.Body.Code = constant.OK
|
||||
rspObj.Generals = make([]proto.General, len(gs))
|
||||
for i, v := range gs {
|
||||
rspObj.Generals[i] = v.ToProto().(proto.General)
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.DBError
|
||||
}
|
||||
}
|
||||
|
||||
func (this*General) composeGeneral(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ComposeGeneralReq{}
|
||||
rspObj := &proto.ComposeGeneralRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
|
||||
gs, ok := mgr.GMgr.HasGeneral(role.RId,reqObj.CompId)
|
||||
//是否有这个武将
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GeneralNoHas
|
||||
return
|
||||
}
|
||||
|
||||
//是否都有这个武将
|
||||
gss ,ok := mgr.GMgr.HasGenerals(role.RId,reqObj.GIds)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GeneralNoHas
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
for _, v := range gss {
|
||||
t := v
|
||||
if t.CfgId != gs.CfgId {
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
|
||||
//是否同一个类型的武将
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.GeneralNoSame
|
||||
return
|
||||
}
|
||||
|
||||
//是否超过武将星级
|
||||
if int(gs.Star - gs.StarLv) < len(gss){
|
||||
rsp.Body.Code = constant.GeneralStarMax
|
||||
return
|
||||
}
|
||||
|
||||
gs.StarLv += int8(len(gss))
|
||||
gs.HasPrPoint += static_conf.Basic.General.PrPoint * len(gss)
|
||||
gs.SyncExecute()
|
||||
|
||||
for _, v := range gss {
|
||||
t := v
|
||||
t.ParentId = gs.Id
|
||||
t.State = model.GeneralComposeStar
|
||||
t.SyncExecute()
|
||||
}
|
||||
|
||||
rspObj.Generals = make([]proto.General, len(gss))
|
||||
for i, v := range gss {
|
||||
rspObj.Generals[i] = v.ToProto().(proto.General)
|
||||
}
|
||||
rspObj.Generals = append(rspObj.Generals,gs.ToProto().(proto.General))
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (this*General) addPrGeneral(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.AddPrGeneralReq{}
|
||||
rspObj := &proto.AddPrGeneralRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
gs, ok := mgr.GMgr.HasGeneral(role.RId,reqObj.CompId)
|
||||
//是否有这个武将
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GeneralNoHas
|
||||
return
|
||||
}
|
||||
|
||||
all:= reqObj.ForceAdd + reqObj.StrategyAdd + reqObj.DefenseAdd + reqObj.SpeedAdd + reqObj.DestroyAdd
|
||||
if gs.HasPrPoint < all{
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
gs.ForceAdded = reqObj.ForceAdd
|
||||
gs.StrategyAdded = reqObj.StrategyAdd
|
||||
gs.DefenseAdded = reqObj.DefenseAdd
|
||||
gs.SpeedAdded = reqObj.SpeedAdd
|
||||
gs.DestroyAdded = reqObj.DestroyAdd
|
||||
|
||||
gs.UsePrPoint = all
|
||||
gs.SyncExecute()
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
rspObj.Generals = gs.ToProto().(proto.General)
|
||||
|
||||
}
|
||||
|
||||
func (this*General) convert(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ConvertReq{}
|
||||
rspObj := &proto.ConvertRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
roleRes, ok:= mgr.RResMgr.Get(role.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
gold := 0
|
||||
okArray := make([]int, 0)
|
||||
for _, gid := range reqObj.GIds {
|
||||
g, ok := mgr.GMgr.GetByGId(gid)
|
||||
if ok && g.Order == 0{
|
||||
okArray = append(okArray, gid)
|
||||
gold += 10* int(g.Star)*(1 + int(g.StarLv))
|
||||
g.State = model.GeneralConvert
|
||||
g.SyncExecute()
|
||||
}
|
||||
}
|
||||
|
||||
roleRes.Gold += gold
|
||||
rspObj.AddGold = gold
|
||||
rspObj.Gold = roleRes.Gold
|
||||
rspObj.GIds = okArray
|
||||
|
||||
roleRes.SyncExecute()
|
||||
}
|
||||
|
||||
func (this*General) upSkill(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.UpDownSkillReq{}
|
||||
rspObj := &proto.UpDownSkillRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
rspObj.Pos = reqObj.Pos
|
||||
rspObj.CfgId = reqObj.CfgId
|
||||
rspObj.GId = reqObj.GId
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if reqObj.Pos <0 || reqObj.Pos >= model.SkillLimit {
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
g,ok := mgr.GMgr.GetByGId(reqObj.GId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GeneralNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if g.RId != role.RId{
|
||||
rsp.Body.Code = constant.GeneralNotMe
|
||||
return
|
||||
}
|
||||
|
||||
skill, ok := mgr.SkillMgr.GetSkillOrCreate(role.RId, reqObj.CfgId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
if skill.IsInLimit() == false{
|
||||
rsp.Body.Code = constant.OutSkillLimit
|
||||
return
|
||||
}
|
||||
|
||||
if skill.ArmyIsIn(g.CurArms) == false{
|
||||
rsp.Body.Code = constant.OutArmNotMatch
|
||||
return
|
||||
}
|
||||
|
||||
if g.UpSkill(skill.Id, reqObj.CfgId, reqObj.Pos) == false{
|
||||
rsp.Body.Code = constant.UpSkillError
|
||||
return
|
||||
}
|
||||
skill.UpSkill(g.Id)
|
||||
g.SyncExecute()
|
||||
skill.SyncExecute()
|
||||
}
|
||||
|
||||
func (this*General) downSkill(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.UpDownSkillReq{}
|
||||
rspObj := &proto.UpDownSkillRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
rspObj.Pos = reqObj.Pos
|
||||
rspObj.CfgId = reqObj.CfgId
|
||||
rspObj.GId = reqObj.GId
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if reqObj.Pos <0 || reqObj.Pos >= model.SkillLimit {
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
g,ok := mgr.GMgr.GetByGId(reqObj.GId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GeneralNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if g.RId != role.RId{
|
||||
rsp.Body.Code = constant.GeneralNotMe
|
||||
return
|
||||
}
|
||||
|
||||
skill, ok := mgr.SkillMgr.GetSkillOrCreate(role.RId, reqObj.CfgId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
if g.DownSkill(skill.Id, reqObj.Pos) == false{
|
||||
rsp.Body.Code = constant.DownSkillError
|
||||
return
|
||||
}
|
||||
skill.DownSkill(g.Id)
|
||||
g.SyncExecute()
|
||||
skill.SyncExecute()
|
||||
}
|
||||
|
||||
func (this*General) lvSkill(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.LvSkillReq{}
|
||||
rspObj := &proto.LvSkillRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
rspObj.Pos = reqObj.Pos
|
||||
rspObj.GId = reqObj.GId
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
g, ok := mgr.GMgr.GetByGId(reqObj.GId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.GeneralNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if g.RId != role.RId {
|
||||
rsp.Body.Code = constant.GeneralNotMe
|
||||
return
|
||||
}
|
||||
|
||||
gSkill, err := g.PosSkill(reqObj.Pos)
|
||||
if err != nil{
|
||||
rsp.Body.Code = constant.PosNotSkill
|
||||
return
|
||||
}
|
||||
|
||||
skillCfg, ok := skill.Skill.GetCfg(gSkill.CfgId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.PosNotSkill
|
||||
return
|
||||
}
|
||||
|
||||
if gSkill.Lv > len(skillCfg.Levels){
|
||||
rsp.Body.Code = constant.SkillLevelFull
|
||||
return
|
||||
}
|
||||
|
||||
gSkill.Lv += 1
|
||||
g.SyncExecute()
|
||||
}
|
||||
200
server/slgserver/controller/interior.go
Normal file
200
server/slgserver/controller/interior.go
Normal file
@@ -0,0 +1,200 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"time"
|
||||
)
|
||||
|
||||
var DefaultInterior = Interior{}
|
||||
|
||||
type Interior struct {
|
||||
|
||||
}
|
||||
|
||||
func (this*Interior) InitRouter(r *net.Router) {
|
||||
g := r.Group("interior").Use(middleware.ElapsedTime(),
|
||||
middleware.Log(), middleware.CheckRole())
|
||||
g.AddRouter("collect", this.collect)
|
||||
g.AddRouter("openCollect", this.openCollect)
|
||||
g.AddRouter("transform", this.transform)
|
||||
|
||||
}
|
||||
|
||||
func (this*Interior) collect(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.CollectionReq{}
|
||||
rspObj := &proto.CollectionRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
roleRes, ok:= mgr.RResMgr.Get(role.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
roleAttr, ok:= mgr.RAttrMgr.Get(role.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
curTime := time.Now()
|
||||
lastTime := roleAttr.LastCollectTime
|
||||
if curTime.YearDay() != lastTime.YearDay() || curTime.Year() != lastTime.Year(){
|
||||
roleAttr.CollectTimes = 0
|
||||
roleAttr.LastCollectTime = time.Time{}
|
||||
}
|
||||
|
||||
timeLimit := static_conf.Basic.Role.CollectTimesLimit
|
||||
//是否超过征收次数上限
|
||||
if roleAttr.CollectTimes >= timeLimit{
|
||||
rsp.Body.Code = constant.OutCollectTimesLimit
|
||||
return
|
||||
}
|
||||
|
||||
//cd内不能操作
|
||||
need := lastTime.Add(time.Duration(static_conf.Basic.Role.CollectTimesLimit)*time.Second)
|
||||
if curTime.Before(need){
|
||||
rsp.Body.Code = constant.InCdCanNotOperate
|
||||
return
|
||||
}
|
||||
|
||||
gold := mgr.GetYield(roleRes.RId).Gold
|
||||
rspObj.Gold = gold
|
||||
roleRes.Gold += gold
|
||||
//更新
|
||||
roleRes.SyncExecute()
|
||||
|
||||
roleAttr.LastCollectTime = curTime
|
||||
roleAttr.CollectTimes += 1
|
||||
roleAttr.SyncExecute()
|
||||
|
||||
interval := static_conf.Basic.Role.CollectInterval
|
||||
if roleAttr.CollectTimes >= timeLimit {
|
||||
y, m, d := roleAttr.LastCollectTime.Add(24*time.Hour).Date()
|
||||
nextTime := time.Date(y, m, d, 0, 0, 0, 0, time.FixedZone("IST", 3600))
|
||||
rspObj.NextTime = nextTime.UnixNano()/1e6
|
||||
}else{
|
||||
nextTime := roleAttr.LastCollectTime.Add(time.Duration(interval)*time.Second)
|
||||
rspObj.NextTime = nextTime.UnixNano()/1e6
|
||||
}
|
||||
|
||||
rspObj.CurTimes = roleAttr.CollectTimes
|
||||
rspObj.Limit = timeLimit
|
||||
|
||||
}
|
||||
|
||||
func (this*Interior) openCollect(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.OpenCollectionReq{}
|
||||
rspObj := &proto.OpenCollectionRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
roleAttr, ok:= mgr.RAttrMgr.Get(role.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
interval := static_conf.Basic.Role.CollectInterval
|
||||
timeLimit := static_conf.Basic.Role.CollectTimesLimit
|
||||
rspObj.Limit = timeLimit
|
||||
rspObj.CurTimes = roleAttr.CollectTimes
|
||||
if roleAttr.LastCollectTime.IsZero() {
|
||||
rspObj.NextTime = 0
|
||||
}else{
|
||||
if roleAttr.CollectTimes >= timeLimit {
|
||||
y, m, d := roleAttr.LastCollectTime.Add(24*time.Hour).Date()
|
||||
nextTime := time.Date(y, m, d, 0, 0, 0, 0, time.FixedZone("IST", 3600))
|
||||
rspObj.NextTime = nextTime.UnixNano()/1e6
|
||||
}else{
|
||||
nextTime := roleAttr.LastCollectTime.Add(time.Duration(interval)*time.Second)
|
||||
rspObj.NextTime = nextTime.UnixNano()/1e6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*Interior) transform(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.TransformReq{}
|
||||
rspObj := &proto.TransformRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
roleRes, ok:= mgr.RResMgr.Get(role.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
main, _ := mgr.RCMgr.GetMainCity(role.RId)
|
||||
|
||||
lv := mgr.RFMgr.GetFacilityLv(main.CityId, facility.JiShi)
|
||||
if lv <= 0{
|
||||
rsp.Body.Code = constant.NotHasJiShi
|
||||
return
|
||||
}
|
||||
|
||||
len := 4
|
||||
ret := make([]int, len)
|
||||
|
||||
for i := 0 ;i < len; i++{
|
||||
//ret[i] = reqObj.To[i] - reqObj.From[i]
|
||||
if reqObj.From[i] > 0{
|
||||
ret[i] = -reqObj.From[i]
|
||||
}
|
||||
|
||||
if reqObj.To[i] > 0{
|
||||
ret[i] = reqObj.To[i]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if roleRes.Wood + ret[0] < 0{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
if roleRes.Iron + ret[1] < 0{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
if roleRes.Stone + ret[2] < 0{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
if roleRes.Grain + ret[3] < 0{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
roleRes.Wood += ret[0]
|
||||
roleRes.Iron += ret[1]
|
||||
roleRes.Stone += ret[2]
|
||||
roleRes.Grain += ret[3]
|
||||
roleRes.SyncExecute()
|
||||
|
||||
}
|
||||
|
||||
274
server/slgserver/controller/nation_map.go
Normal file
274
server/slgserver/controller/nation_map.go
Normal file
@@ -0,0 +1,274 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/logic"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
)
|
||||
|
||||
var DefaultMap = NationMap{}
|
||||
|
||||
type NationMap struct {
|
||||
|
||||
}
|
||||
|
||||
func (this*NationMap) InitRouter(r *net.Router) {
|
||||
g := r.Group("nationMap").Use(middleware.ElapsedTime(), middleware.Log())
|
||||
g.AddRouter("config", this.config)
|
||||
g.AddRouter("scan", this.scan, middleware.CheckRole())
|
||||
g.AddRouter("scanBlock", this.scanBlock, middleware.CheckRole())
|
||||
g.AddRouter("giveUp", this.giveUp, middleware.CheckRole())
|
||||
g.AddRouter("build", this.build, middleware.CheckRole())
|
||||
g.AddRouter("upBuild", this.upBuild, middleware.CheckRole())
|
||||
g.AddRouter("delBuild", this.delBuild, middleware.CheckRole())
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
获取配置
|
||||
*/
|
||||
func (this*NationMap) config(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ConfigReq{}
|
||||
rspObj := &proto.ConfigRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
m := static_conf.MapBuildConf.Cfg
|
||||
rspObj.Confs = make([]proto.Conf, len(m))
|
||||
i := 0
|
||||
for _, v := range m {
|
||||
rspObj.Confs[i].Type = v.Type
|
||||
rspObj.Confs[i].Name = v.Name
|
||||
rspObj.Confs[i].Level = v.Level
|
||||
rspObj.Confs[i].Defender = v.Defender
|
||||
rspObj.Confs[i].Durable = v.Durable
|
||||
rspObj.Confs[i].Grain = v.Grain
|
||||
rspObj.Confs[i].Iron = v.Iron
|
||||
rspObj.Confs[i].Stone = v.Stone
|
||||
rspObj.Confs[i].Wood = v.Wood
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
扫描地图
|
||||
*/
|
||||
func (this*NationMap) scan(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ScanReq{}
|
||||
rspObj := &proto.ScanRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
x := reqObj.X
|
||||
y := reqObj.Y
|
||||
|
||||
rb := mgr.RBMgr.Scan(x, y)
|
||||
rspObj.MRBuilds = make([]proto.MapRoleBuild, len(rb))
|
||||
for i, v := range rb {
|
||||
rspObj.MRBuilds[i] = v.ToProto().(proto.MapRoleBuild)
|
||||
}
|
||||
|
||||
cb := mgr.RCMgr.Scan(x, y)
|
||||
rspObj.MCBuilds = make([]proto.MapRoleCity, len(cb))
|
||||
for i, v := range cb {
|
||||
rspObj.MCBuilds[i] = v.ToProto().(proto.MapRoleCity)
|
||||
}
|
||||
}
|
||||
|
||||
func (this*NationMap) scanBlock(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.ScanBlockReq{}
|
||||
rspObj := &proto.ScanRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
x := reqObj.X
|
||||
y := reqObj.Y
|
||||
|
||||
rb := mgr.RBMgr.ScanBlock(x, y, reqObj.Length)
|
||||
rspObj.MRBuilds = make([]proto.MapRoleBuild, len(rb))
|
||||
for i, v := range rb {
|
||||
rspObj.MRBuilds[i] = v.ToProto().(proto.MapRoleBuild)
|
||||
}
|
||||
|
||||
cb := mgr.RCMgr.ScanBlock(x, y, reqObj.Length)
|
||||
rspObj.MCBuilds = make([]proto.MapRoleCity, len(cb))
|
||||
for i, v := range cb {
|
||||
rspObj.MCBuilds[i] = v.ToProto().(proto.MapRoleCity)
|
||||
}
|
||||
|
||||
armys := logic.ArmyLogic.ScanBlock(role.RId, x, y, reqObj.Length)
|
||||
rspObj.Armys = make([]proto.Army, len(armys))
|
||||
for i, v := range armys {
|
||||
rspObj.Armys[i] = v.ToProto().(proto.Army)
|
||||
}
|
||||
}
|
||||
|
||||
func (this*NationMap) giveUp(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.GiveUpReq{}
|
||||
rspObj := &proto.GiveUpRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
x := reqObj.X
|
||||
y := reqObj.Y
|
||||
|
||||
rspObj.X = x
|
||||
rspObj.Y = y
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if mgr.RBMgr.BuildIsRId(x, y, role.RId) == false{
|
||||
rsp.Body.Code = constant.BuildNotMe
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Body.Code = mgr.RBMgr.GiveUp(x, y)
|
||||
}
|
||||
|
||||
//建造
|
||||
func (this*NationMap) build(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.BuildReq{}
|
||||
rspObj := &proto.BuildRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
x := reqObj.X
|
||||
y := reqObj.Y
|
||||
|
||||
rspObj.X = x
|
||||
rspObj.Y = y
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if mgr.RBMgr.BuildIsRId(x, y, role.RId) == false{
|
||||
rsp.Body.Code = constant.BuildNotMe
|
||||
return
|
||||
}
|
||||
|
||||
b, ok := mgr.RBMgr.PositionBuild(x, y)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.BuildNotMe
|
||||
return
|
||||
}
|
||||
|
||||
if b.IsResBuild() == false || b.IsBusy(){
|
||||
rsp.Body.Code = constant.CanNotBuildNew
|
||||
return
|
||||
}
|
||||
|
||||
cnt := mgr.RBMgr.RoleFortressCnt(role.RId)
|
||||
if cnt >= static_conf.Basic.Build.FortressLimit{
|
||||
rsp.Body.Code = constant.CanNotBuildNew
|
||||
return
|
||||
}
|
||||
|
||||
cfg, ok := static_conf.MapBCConf.BuildConfig(reqObj.Type, 1)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
code := mgr.RResMgr.TryUseNeed(role.RId, cfg.Need)
|
||||
if code != constant.OK {
|
||||
rsp.Body.Code = code
|
||||
return
|
||||
}
|
||||
|
||||
b.BuildOrUp(*cfg)
|
||||
b.SyncExecute()
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (this*NationMap) upBuild(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.UpBuildReq{}
|
||||
rspObj := &proto.UpBuildRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
x := reqObj.X
|
||||
y := reqObj.Y
|
||||
|
||||
rspObj.X = x
|
||||
rspObj.Y = y
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if mgr.RBMgr.BuildIsRId(x, y, role.RId) == false{
|
||||
rsp.Body.Code = constant.BuildNotMe
|
||||
return
|
||||
}
|
||||
|
||||
b, ok := mgr.RBMgr.PositionBuild(x, y)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.BuildNotMe
|
||||
return
|
||||
}
|
||||
|
||||
if b.IsHaveModifyLVAuth() == false || b.IsInGiveUp() || b.IsBusy(){
|
||||
rsp.Body.Code = constant.CanNotUpBuild
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
cfg, ok := static_conf.MapBCConf.BuildConfig(b.Type, b.Level+1)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
return
|
||||
}
|
||||
|
||||
code := mgr.RResMgr.TryUseNeed(role.RId, cfg.Need)
|
||||
if code != constant.OK {
|
||||
rsp.Body.Code = code
|
||||
return
|
||||
}
|
||||
b.BuildOrUp(*cfg)
|
||||
b.SyncExecute()
|
||||
rspObj.Build = b.ToProto().(proto.MapRoleBuild)
|
||||
}
|
||||
|
||||
func (this*NationMap) delBuild(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.UpBuildReq{}
|
||||
rspObj := &proto.UpBuildRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
x := reqObj.X
|
||||
y := reqObj.Y
|
||||
|
||||
rspObj.X = x
|
||||
rspObj.Y = y
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if mgr.RBMgr.BuildIsRId(x, y, role.RId) == false{
|
||||
rsp.Body.Code = constant.BuildNotMe
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Body.Code = mgr.RBMgr.Destroy(x, y)
|
||||
b, ok := mgr.RBMgr.PositionBuild(x, y)
|
||||
if ok {
|
||||
rspObj.Build = b.ToProto().(proto.MapRoleBuild)
|
||||
}
|
||||
}
|
||||
412
server/slgserver/controller/role.go
Normal file
412
server/slgserver/controller/role.go
Normal file
@@ -0,0 +1,412 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/pos"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
var DefaultRole = Role{}
|
||||
|
||||
type Role struct {
|
||||
|
||||
}
|
||||
|
||||
func (this*Role) InitRouter(r *net.Router) {
|
||||
g := r.Group("role").Use(middleware.ElapsedTime(), middleware.Log())
|
||||
|
||||
g.AddRouter("enterServer", this.enterServer)
|
||||
g.AddRouter("create", this.create, middleware.CheckLogin())
|
||||
g.AddRouter("roleList", this.roleList, middleware.CheckLogin())
|
||||
g.AddRouter("myCity", this.myCity, middleware.CheckRole())
|
||||
g.AddRouter("myRoleRes", this.myRoleRes, middleware.CheckRole())
|
||||
g.AddRouter("myRoleBuild", this.myRoleBuild, middleware.CheckRole())
|
||||
g.AddRouter("myProperty", this.myProperty, middleware.CheckRole())
|
||||
g.AddRouter("upPosition", this.upPosition, middleware.CheckRole())
|
||||
g.AddRouter("posTagList", this.posTagList, middleware.CheckRole())
|
||||
g.AddRouter("opPosTag", this.opPosTag, middleware.CheckRole())
|
||||
}
|
||||
|
||||
func (this*Role) create(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.CreateRoleReq{}
|
||||
rspObj := &proto.CreateRoleRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
|
||||
uid, _ := req.Conn.GetProperty("uid")
|
||||
reqObj.UId = uid.(int)
|
||||
rspObj.Role.UId = reqObj.UId
|
||||
|
||||
r := make([]model.Role, 0)
|
||||
has, _ := db.MasterDB.Table(r).Where("uid=?", reqObj.UId).Get(r)
|
||||
if has {
|
||||
slog.Info("role has create", "uid", reqObj.UId)
|
||||
rsp.Body.Code = constant.RoleAlreadyCreate
|
||||
}else {
|
||||
|
||||
role := &model.Role{UId: reqObj.UId, HeadId: reqObj.HeadId, Sex: reqObj.Sex,
|
||||
NickName: reqObj.NickName, CreatedAt: time.Now()}
|
||||
|
||||
if _, err := db.MasterDB.Insert(role); err != nil {
|
||||
slog.Info("role create error",
|
||||
"uid", reqObj.UId, "error", err)
|
||||
rsp.Body.Code = constant.DBError
|
||||
}else{
|
||||
rspObj.Role.RId = role.RId
|
||||
rspObj.Role.UId = reqObj.UId
|
||||
rspObj.Role.NickName = reqObj.NickName
|
||||
rspObj.Role.Sex = reqObj.Sex
|
||||
rspObj.Role.HeadId = reqObj.HeadId
|
||||
|
||||
rsp.Body.Code = constant.OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*Role) roleList(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.RoleListReq{}
|
||||
rspObj := &proto.RoleListRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
uid, _ := req.Conn.GetProperty("uid")
|
||||
uid = uid.(int)
|
||||
|
||||
r := make([]*model.Role, 0)
|
||||
err := db.MasterDB.Table(r).Where("uid=?", uid).Find(&r)
|
||||
if err == nil{
|
||||
rl := make([]proto.Role, len(r))
|
||||
for i, v := range r {
|
||||
rl[i] = v.ToProto().(proto.Role)
|
||||
}
|
||||
rspObj.Roles = rl
|
||||
rsp.Body.Code = constant.OK
|
||||
}else{
|
||||
rsp.Body.Code = constant.DBError
|
||||
}
|
||||
}
|
||||
|
||||
func (this*Role) enterServer(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.EnterServerReq{}
|
||||
rspObj := &proto.EnterServerRsp{}
|
||||
rspObj.Time = time.Now().UnixNano()/1e6
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
//校验session是否合法
|
||||
sess, err := util.ParseSession(reqObj.Session)
|
||||
if err != nil || sess.IsValid() == false{
|
||||
rsp.Body.Code = constant.SessionInvalid
|
||||
return
|
||||
}
|
||||
uid := sess.Id
|
||||
req.Conn.SetProperty("uid", uid)
|
||||
//查询角色
|
||||
role := &model.Role{}
|
||||
b, err := db.MasterDB.Table(role).Where("uid=?", uid).Get(role)
|
||||
if err != nil{
|
||||
slog.Warn("enterServer db error", "error", err)
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
if b {
|
||||
rsp.Body.Code = constant.OK
|
||||
rspObj.Role = role.ToProto().(proto.Role)
|
||||
req.Conn.SetProperty("role", role)
|
||||
net.ConnMgr.RoleEnter(req.Conn, role.RId)
|
||||
|
||||
var e error = nil
|
||||
roleRes, ok := mgr.RResMgr.Get(role.RId)
|
||||
if ok == false{
|
||||
|
||||
roleRes = &model.RoleRes{RId: role.RId,
|
||||
Wood: static_conf.Basic.Role.Wood,
|
||||
Iron: static_conf.Basic.Role.Iron,
|
||||
Stone: static_conf.Basic.Role.Stone,
|
||||
Grain: static_conf.Basic.Role.Grain,
|
||||
Gold: static_conf.Basic.Role.Gold,
|
||||
Decree: static_conf.Basic.Role.Decree}
|
||||
_ ,e = db.MasterDB.Insert(roleRes)
|
||||
if e != nil {
|
||||
slog.Error("insert rres error", "error", e)
|
||||
}
|
||||
}
|
||||
|
||||
if e == nil {
|
||||
mgr.RResMgr.Add(roleRes)
|
||||
rspObj.RoleRes = roleRes.ToProto().(proto.RoleRes)
|
||||
rsp.Body.Code = constant.OK
|
||||
}else{
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
//玩家的一些属性
|
||||
if _, ok := mgr.RAttrMgr.TryCreate(role.RId); ok == false{
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
//查询是否有城市
|
||||
_, ok = mgr.RCMgr.GetByRId(role.RId)
|
||||
if ok == false{
|
||||
citys := make([]*model.MapRoleCity, 0)
|
||||
//随机生成一个城市
|
||||
for true {
|
||||
x := rand.Intn(global.MapWith)
|
||||
y := rand.Intn(global.MapHeight)
|
||||
if mgr.NMMgr.IsCanBuildCity(x, y){
|
||||
//建立城市
|
||||
c := &model.MapRoleCity{RId: role.RId, X: x, Y: y,
|
||||
IsMain: 1,
|
||||
CurDurable: static_conf.Basic.City.Durable,
|
||||
Name: role.NickName,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
//插入
|
||||
_, err := db.MasterDB.Table(c).Insert(c)
|
||||
if err != nil{
|
||||
rsp.Body.Code = constant.DBError
|
||||
}else{
|
||||
citys = append(citys, c)
|
||||
//更新城市缓存
|
||||
mgr.RCMgr.Add(c)
|
||||
}
|
||||
|
||||
//生成城市里面的设施
|
||||
mgr.RFMgr.GetAndTryCreate(c.CityId, c.RId)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
rspObj.Token = util.NewSession(role.RId, time.Now()).String()
|
||||
}else{
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
}
|
||||
}
|
||||
|
||||
func (this*Role) myCity(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.MyCityReq{}
|
||||
rspObj := &proto.MyCityRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role, _ := r.(*model.Role)
|
||||
|
||||
|
||||
citys,ok := mgr.RCMgr.GetByRId(role.RId)
|
||||
if ok {
|
||||
rspObj.Citys = make([]proto.MapRoleCity, len(citys))
|
||||
//赋值发送
|
||||
for i, v := range citys {
|
||||
rspObj.Citys[i] = v.ToProto().(proto.MapRoleCity)
|
||||
}
|
||||
|
||||
}else{
|
||||
rspObj.Citys = make([]proto.MapRoleCity, 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this*Role) myRoleRes(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.MyRoleResReq{}
|
||||
rspObj := &proto.MyRoleResRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
roleRes, ok := mgr.RResMgr.Get(role.RId)
|
||||
if ok == false{
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}else{
|
||||
rspObj.RoleRes = roleRes.ToProto().(proto.RoleRes)
|
||||
rsp.Body.Code = constant.OK
|
||||
}
|
||||
}
|
||||
|
||||
func (this*Role) myProperty(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.MyRolePropertyReq{}
|
||||
rspObj := &proto.MyRolePropertyRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
//城市
|
||||
c, ok := mgr.RCMgr.GetByRId(role.RId)
|
||||
if ok {
|
||||
rspObj.Citys = make([]proto.MapRoleCity, len(c))
|
||||
for i, v := range c {
|
||||
rspObj.Citys[i] = v.ToProto().(proto.MapRoleCity)
|
||||
}
|
||||
}else{
|
||||
rspObj.Citys = make([]proto.MapRoleCity, 0)
|
||||
}
|
||||
|
||||
|
||||
//建筑
|
||||
ra, ok := mgr.RBMgr.GetRoleBuild(role.RId)
|
||||
if ok {
|
||||
rspObj.MRBuilds = make([]proto.MapRoleBuild, len(ra))
|
||||
for i, v := range ra {
|
||||
rspObj.MRBuilds[i] = v.ToProto().(proto.MapRoleBuild)
|
||||
}
|
||||
}else{
|
||||
rspObj.MRBuilds = make([]proto.MapRoleBuild, 0)
|
||||
}
|
||||
|
||||
//资源
|
||||
roleRes, ok := mgr.RResMgr.Get(role.RId)
|
||||
if ok {
|
||||
rspObj.RoleRes = roleRes.ToProto().(proto.RoleRes)
|
||||
}else{
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}
|
||||
|
||||
//武将
|
||||
gs, ok := mgr.GMgr.GetOrCreateByRId(role.RId)
|
||||
if ok {
|
||||
rspObj.Generals = make([]proto.General, 0)
|
||||
for _, v := range gs {
|
||||
rspObj.Generals = append(rspObj.Generals, v.ToProto().(proto.General))
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
//军队
|
||||
ar, ok := mgr.AMgr.GetByRId(role.RId)
|
||||
if ok {
|
||||
rspObj.Armys = make([]proto.Army, len(ar))
|
||||
for i, v := range ar {
|
||||
rspObj.Armys[i] = v.ToProto().(proto.Army)
|
||||
}
|
||||
}else{
|
||||
rspObj.Armys = make([]proto.Army, 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this*Role) myRoleBuild(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.MyRoleBuildReq{}
|
||||
rspObj := &proto.MyRoleBuildRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
ra, ok := mgr.RBMgr.GetRoleBuild(role.RId)
|
||||
if ok {
|
||||
rspObj.MRBuilds = make([]proto.MapRoleBuild, len(ra))
|
||||
for i, v := range ra {
|
||||
rspObj.MRBuilds[i] = v.ToProto().(proto.MapRoleBuild)
|
||||
}
|
||||
}else{
|
||||
rspObj.MRBuilds = make([]proto.MapRoleBuild, 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this*Role) upPosition(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.UpPositionReq{}
|
||||
rspObj := &proto.UpPositionRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
rspObj.X = reqObj.X
|
||||
rspObj.Y = reqObj.Y
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
pos.RPMgr.Push(reqObj.X, reqObj.Y, role.RId)
|
||||
|
||||
}
|
||||
|
||||
func (this*Role) posTagList(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.PosTagListReq{}
|
||||
rspObj := &proto.PosTagListRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
attr, ok := mgr.RAttrMgr.Get(role.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}
|
||||
|
||||
rspObj.PosTags = attr.PosTagArray
|
||||
|
||||
}
|
||||
|
||||
func (this*Role) opPosTag(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.PosTagReq{}
|
||||
rspObj := &proto.PosTagRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
rspObj.X = reqObj.X
|
||||
rspObj.Y = reqObj.Y
|
||||
rspObj.Type = reqObj.Type
|
||||
rspObj.Name = reqObj.Name
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
attr, ok := mgr.RAttrMgr.Get(role.RId)
|
||||
if ok == false {
|
||||
rsp.Body.Code = constant.RoleNotExist
|
||||
return
|
||||
}
|
||||
if reqObj.Type == 0{
|
||||
attr.RemovePosTag(reqObj.X, reqObj.Y)
|
||||
attr.SyncExecute()
|
||||
}else if reqObj.Type == 1{
|
||||
|
||||
limit := static_conf.Basic.Role.PosTagLimit
|
||||
if int(limit) >= len(attr.PosTagArray){
|
||||
attr.AddPosTag(reqObj.X, reqObj.Y, reqObj.Name)
|
||||
attr.SyncExecute()
|
||||
}else{
|
||||
rsp.Body.Code = constant.OutPosTagLimit
|
||||
}
|
||||
}else{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
}
|
||||
}
|
||||
|
||||
42
server/slgserver/controller/skill.go
Normal file
42
server/slgserver/controller/skill.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"slgserver/constant"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
)
|
||||
|
||||
var DefaultSkill = Skill{
|
||||
|
||||
}
|
||||
type Skill struct {
|
||||
|
||||
}
|
||||
|
||||
func (this*Skill) InitRouter(r *net.Router) {
|
||||
g := r.Group("skill").Use(middleware.ElapsedTime(), middleware.Log(),
|
||||
middleware.CheckLogin(), middleware.CheckRole())
|
||||
|
||||
g.AddRouter("list", this.list)
|
||||
|
||||
}
|
||||
|
||||
func (this*Skill) list(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.SkillListReq{}
|
||||
rspObj := &proto.SkillListRsp{}
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
rspObj.List = make([]proto.Skill, 0)
|
||||
skills, _ := mgr.SkillMgr.Get(role.RId)
|
||||
for _, skill := range skills {
|
||||
rspObj.List = append(rspObj.List, skill.ToProto().(proto.Skill))
|
||||
}
|
||||
}
|
||||
103
server/slgserver/controller/war.go
Normal file
103
server/slgserver/controller/war.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
"slgserver/middleware"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
)
|
||||
|
||||
var DefaultWar = War{}
|
||||
|
||||
type War struct {
|
||||
|
||||
}
|
||||
|
||||
func (this*War) InitRouter(r *net.Router) {
|
||||
g := r.Group("war").Use(middleware.ElapsedTime(),
|
||||
middleware.Log(), middleware.CheckRole())
|
||||
g.AddRouter("report", this.report)
|
||||
g.AddRouter("read", this.read)
|
||||
}
|
||||
|
||||
func (this*War) report(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.WarReportReq{}
|
||||
rspObj := &proto.WarReportRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
//查询最近30条战报吧
|
||||
l := make([]*model.WarReport, 0)
|
||||
err := db.MasterDB.Table(model.WarReport{}).Where("a_rid=? or d_rid=?",
|
||||
role.RId, role.RId).Desc("ctime").Limit(100, 0).Find(&l)
|
||||
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
rspObj.List = make([]proto.WarReport, len(l))
|
||||
for i, v := range l {
|
||||
rspObj.List[i] = v.ToProto().(proto.WarReport)
|
||||
}
|
||||
}
|
||||
|
||||
func (this*War) read(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
reqObj := &proto.WarReadReq{}
|
||||
rspObj := &proto.WarReadRsp{}
|
||||
|
||||
mapstructure.Decode(req.Body.Msg, reqObj)
|
||||
rsp.Body.Msg = rspObj
|
||||
rsp.Body.Code = constant.OK
|
||||
rspObj.Id = reqObj.Id
|
||||
|
||||
r, _ := req.Conn.GetProperty("role")
|
||||
role := r.(*model.Role)
|
||||
|
||||
if reqObj.Id == 0 {
|
||||
m := model.WarReport{AttackIsRead: true, DefenseIsRead: true}
|
||||
_, err := db.MasterDB.Table(model.WarReport{}).Where("a_rid=?", role.RId).Cols("a_is_read").Update(m)
|
||||
if err != nil {
|
||||
slog.Error("db error", "error", err)
|
||||
}
|
||||
_, err = db.MasterDB.Table(model.WarReport{}).Where("d_rid=?", role.RId).Cols("d_is_read").Update(m)
|
||||
if err != nil {
|
||||
slog.Error("db error", "error", err)
|
||||
}
|
||||
}else{
|
||||
wr := &model.WarReport{}
|
||||
ok, err := db.MasterDB.Table(model.WarReport{}).Where("id=?",
|
||||
reqObj.Id).Get(wr)
|
||||
|
||||
if err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
rsp.Body.Code = constant.DBError
|
||||
return
|
||||
}
|
||||
|
||||
if ok {
|
||||
if wr.AttackRid == role.RId {
|
||||
wr.AttackIsRead = true
|
||||
db.MasterDB.Table(wr).ID(wr.Id).Cols("a_is_read").Update(wr)
|
||||
rsp.Body.Code = constant.OK
|
||||
}else if wr.DefenseRid == role.RId {
|
||||
wr.DefenseIsRead = true
|
||||
db.MasterDB.Table(wr).ID(wr.Id).Cols("d_is_read").Update(wr)
|
||||
rsp.Body.Code = constant.OK
|
||||
}else{
|
||||
rsp.Body.Code = constant.InvalidParam
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
server/slgserver/global/global.go
Normal file
8
server/slgserver/global/global.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package global
|
||||
|
||||
var MapWith = 200
|
||||
var MapHeight = 200
|
||||
|
||||
func ToPosition(x, y int) int {
|
||||
return x+ MapHeight*y
|
||||
}
|
||||
456
server/slgserver/logic/army_logic.go
Normal file
456
server/slgserver/logic/army_logic.go
Normal file
@@ -0,0 +1,456 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type armyLogic struct {
|
||||
sys *sysArmyLogic
|
||||
passBy sync.RWMutex
|
||||
stop sync.RWMutex
|
||||
out sync.RWMutex
|
||||
endTime sync.RWMutex
|
||||
|
||||
interruptId chan int
|
||||
giveUpId chan int
|
||||
arriveArmys chan *model.Army
|
||||
updateArmys chan *model.Army
|
||||
|
||||
outArmys map[int]*model.Army //城外的军队
|
||||
endTimeArmys map[int64][]*model.Army //key:到达时间
|
||||
stopInPosArmys map[int]map[int]*model.Army //玩家停留位置的军队 key:posId,armyId
|
||||
passByPosArmys map[int]map[int]*model.Army //玩家路过位置的军队 key:posId,armyId
|
||||
}
|
||||
|
||||
func (this *armyLogic) init(){
|
||||
|
||||
armys := mgr.AMgr.All()
|
||||
for _, army := range armys {
|
||||
//恢复已经执行行动的军队
|
||||
if army.Cmd != model.ArmyCmdIdle {
|
||||
e := army.End.Unix()
|
||||
_, ok := this.endTimeArmys[e]
|
||||
if ok == false{
|
||||
this.endTimeArmys[e] = make([]*model.Army, 0)
|
||||
}
|
||||
this.endTimeArmys[e] = append(this.endTimeArmys[e], army)
|
||||
}
|
||||
}
|
||||
|
||||
curTime := time.Now().Unix()
|
||||
for kT, armys := range this.endTimeArmys {
|
||||
if kT <= curTime {
|
||||
for _, a := range armys {
|
||||
if a.Cmd == model.ArmyCmdAttack {
|
||||
this.Arrive(a)
|
||||
}else if a.Cmd == model.ArmyCmdDefend {
|
||||
this.Arrive(a)
|
||||
}else if a.Cmd == model.ArmyCmdBack {
|
||||
if curTime >= a.End.Unix() {
|
||||
a.ToX = a.FromX
|
||||
a.ToY = a.FromY
|
||||
a.Cmd = model.ArmyCmdIdle
|
||||
a.State = model.ArmyStop
|
||||
}
|
||||
}
|
||||
a.SyncExecute()
|
||||
}
|
||||
delete(this.endTimeArmys, kT)
|
||||
}else{
|
||||
for _, a := range armys {
|
||||
a.State = model.ArmyRunning
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*armyLogic) check() {
|
||||
for true {
|
||||
t := time.Now().Unix()
|
||||
time.Sleep(100*time.Millisecond)
|
||||
|
||||
this.endTime.Lock()
|
||||
for k, armies := range this.endTimeArmys {
|
||||
if k <= t{
|
||||
for _, army := range armies {
|
||||
this.Arrive(army)
|
||||
}
|
||||
delete(this.endTimeArmys, k)
|
||||
}
|
||||
}
|
||||
this.endTime.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (this *armyLogic) running(){
|
||||
passbyTimer := time.NewTicker(10 * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-passbyTimer.C:{
|
||||
this.updatePassBy()
|
||||
}
|
||||
case army := <-this.updateArmys:{
|
||||
this.exeUpdate(army)
|
||||
}
|
||||
case army := <-this.arriveArmys:{
|
||||
this.exeArrive(army)
|
||||
}
|
||||
case giveId := <- this.giveUpId:{
|
||||
//在该位置驻守、调动的都需要返回
|
||||
this.stop.RLock()
|
||||
armys, ok := this.stopInPosArmys[giveId]
|
||||
this.stop.RUnlock()
|
||||
|
||||
if ok {
|
||||
for _, army := range armys {
|
||||
this.ArmyBack(army)
|
||||
}
|
||||
this.deleteStopArmy(giveId)
|
||||
}
|
||||
}
|
||||
case interruptId := <- this.interruptId:{
|
||||
//只有调动到该位置的军队需要返回
|
||||
var targets []*model.Army
|
||||
this.stop.Lock()
|
||||
armys, ok := this.stopInPosArmys[interruptId]
|
||||
if ok {
|
||||
for key, army := range armys {
|
||||
if army.FromX == army.ToX && army.FromY == army.ToY{
|
||||
targets = append(targets, army)
|
||||
delete(armys, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.stop.Unlock()
|
||||
|
||||
for _, target := range targets {
|
||||
this.ArmyBack(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this* armyLogic) updatePassBy() {
|
||||
|
||||
temp := make(map[int]map[int]*model.Army)
|
||||
this.out.RLock()
|
||||
for _, army := range this.outArmys {
|
||||
if army.State == model.ArmyRunning {
|
||||
x, y := army.Position()
|
||||
posId := global.ToPosition(x, y)
|
||||
if _, ok := temp[posId]; ok == false {
|
||||
temp[posId] = make(map[int]*model.Army)
|
||||
}
|
||||
temp[posId][army.Id] = army
|
||||
army.CheckSyncCell()
|
||||
}
|
||||
}
|
||||
this.out.RUnlock()
|
||||
|
||||
this.stop.RLock()
|
||||
for posId, armys := range this.stopInPosArmys {
|
||||
for _, army := range armys {
|
||||
if _, ok := temp[posId]; ok == false {
|
||||
temp[posId] = make(map[int]*model.Army)
|
||||
}
|
||||
temp[posId][army.Id] = army
|
||||
}
|
||||
}
|
||||
this.stop.RUnlock()
|
||||
|
||||
this.passBy.Lock()
|
||||
this.passByPosArmys = temp
|
||||
this.passBy.Unlock()
|
||||
}
|
||||
|
||||
func (this *armyLogic) exeUpdate(army *model.Army) {
|
||||
army.SyncExecute()
|
||||
if army.Cmd == model.ArmyCmdBack {
|
||||
this.stop.Lock()
|
||||
posId := global.ToPosition(army.ToX, army.ToY)
|
||||
armys, ok := this.stopInPosArmys[posId]
|
||||
if ok {
|
||||
delete(armys, army.Id)
|
||||
this.stopInPosArmys[posId] = armys
|
||||
}
|
||||
this.stop.Unlock()
|
||||
}
|
||||
|
||||
this.out.Lock()
|
||||
if army.Cmd != model.ArmyCmdIdle {
|
||||
this.outArmys[army.Id] = army
|
||||
}else{
|
||||
delete(this.outArmys, army.RId)
|
||||
}
|
||||
this.out.Unlock()
|
||||
}
|
||||
|
||||
func (this *armyLogic) exeArrive(army *model.Army) {
|
||||
if army.Cmd == model.ArmyCmdAttack {
|
||||
if IsCanArrive(army.ToX, army.ToY, army.RId) &&
|
||||
IsWarFree(army.ToX, army.ToY) == false &&
|
||||
IsCanDefend(army.ToX, army.ToY, army.RId) == false{
|
||||
newBattle(army)
|
||||
} else{
|
||||
war := NewEmptyWar(army)
|
||||
war.SyncExecute()
|
||||
}
|
||||
this.ArmyBack(army)
|
||||
}else if army.Cmd == model.ArmyCmdDefend {
|
||||
//呆在哪里不动
|
||||
ok := IsCanDefend(army.ToX, army.ToY, army.RId)
|
||||
if ok {
|
||||
//目前是自己的领地才能驻守
|
||||
army.State = model.ArmyStop
|
||||
this.addStopArmy(army)
|
||||
this.Update(army)
|
||||
}else{
|
||||
war := NewEmptyWar(army)
|
||||
war.SyncExecute()
|
||||
this.ArmyBack(army)
|
||||
}
|
||||
|
||||
}else if army.Cmd == model.ArmyCmdReclamation {
|
||||
if army.State == model.ArmyRunning {
|
||||
|
||||
ok := mgr.RBMgr.BuildIsRId(army.ToX, army.ToY, army.RId)
|
||||
if ok {
|
||||
//目前是自己的领地才能屯田
|
||||
this.addStopArmy(army)
|
||||
this.Reclamation(army)
|
||||
}else{
|
||||
war := NewEmptyWar(army)
|
||||
war.SyncExecute()
|
||||
this.ArmyBack(army)
|
||||
}
|
||||
|
||||
}else {
|
||||
this.ArmyBack(army)
|
||||
//增加场量
|
||||
rr, ok := mgr.RResMgr.Get(army.RId)
|
||||
if ok {
|
||||
b, ok1 := mgr.RBMgr.PositionBuild(army.ToX, army.ToY)
|
||||
if ok1 {
|
||||
rr.Stone += b.Stone
|
||||
rr.Iron += b.Iron
|
||||
rr.Wood += b.Wood
|
||||
rr.Gold += rr.Gold
|
||||
rr.Grain += rr.Grain
|
||||
rr.SyncExecute()
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if army.Cmd == model.ArmyCmdBack {
|
||||
army.State = model.ArmyStop
|
||||
army.Cmd = model.ArmyCmdIdle
|
||||
army.ToX = army.FromX
|
||||
army.ToY = army.FromY
|
||||
|
||||
this.Update(army)
|
||||
}else if army.Cmd == model.ArmyCmdTransfer {
|
||||
//调动到位置了
|
||||
if army.State == model.ArmyRunning{
|
||||
|
||||
ok := mgr.RBMgr.BuildIsRId(army.ToX, army.ToY, army.RId)
|
||||
if ok == false{
|
||||
this.ArmyBack(army)
|
||||
}else{
|
||||
b, _ := mgr.RBMgr.PositionBuild(army.ToX, army.ToY)
|
||||
if b.IsHasTransferAuth(){
|
||||
army.State = model.ArmyStop
|
||||
army.Cmd = model.ArmyCmdIdle
|
||||
x := army.ToX
|
||||
y := army.ToY
|
||||
army.FromX = x
|
||||
army.FromY = y
|
||||
army.ToX = x
|
||||
army.ToY = y
|
||||
this.addStopArmy(army)
|
||||
this.Update(army)
|
||||
}else{
|
||||
this.ArmyBack(army)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *armyLogic) ScanBlock(rid, x, y, length int) []*model.Army {
|
||||
|
||||
if x < 0 || x >= global.MapWith || y < 0 || y >= global.MapHeight {
|
||||
return nil
|
||||
}
|
||||
|
||||
maxX := util.MinInt(global.MapWith, x+length-1)
|
||||
maxY := util.MinInt(global.MapHeight, y+length-1)
|
||||
out := make([]*model.Army, 0)
|
||||
|
||||
this.passBy.RLock()
|
||||
for i := x; i <= maxX; i++ {
|
||||
for j := y; j <= maxY; j++ {
|
||||
|
||||
posId := global.ToPosition(i, j)
|
||||
armys, ok := this.passByPosArmys[posId]
|
||||
if ok {
|
||||
is := armyIsInView(rid, i, j)
|
||||
if is == false{
|
||||
continue
|
||||
}
|
||||
for _, army := range armys {
|
||||
out = append(out, army)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.passBy.RUnlock()
|
||||
return out
|
||||
}
|
||||
|
||||
func (this *armyLogic) Arrive(army *model.Army) {
|
||||
this.arriveArmys <- army
|
||||
}
|
||||
|
||||
func (this *armyLogic) Update(army *model.Army) {
|
||||
this.updateArmys <- army
|
||||
}
|
||||
|
||||
func (this *armyLogic) Interrupt(posId int) {
|
||||
this.interruptId <- posId
|
||||
}
|
||||
|
||||
func (this *armyLogic) GiveUp(posId int) {
|
||||
this.giveUpId <- posId
|
||||
}
|
||||
|
||||
func (this* armyLogic) GetStopArmys(posId int)[]*model.Army {
|
||||
ret := make([]*model.Army, 0)
|
||||
this.stop.RLock()
|
||||
armys, ok := this.stopInPosArmys[posId]
|
||||
if ok {
|
||||
for _, army := range armys {
|
||||
ret = append(ret, army)
|
||||
}
|
||||
}
|
||||
this.stop.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (this *armyLogic) deleteStopArmy(posId int) {
|
||||
this.stop.Lock()
|
||||
delete(this.stopInPosArmys, posId)
|
||||
this.stop.Unlock()
|
||||
}
|
||||
|
||||
func (this*armyLogic) addStopArmy(army *model.Army) {
|
||||
posId := global.ToPosition(army.ToX, army.ToY)
|
||||
|
||||
this.stop.Lock()
|
||||
if _, ok := this.stopInPosArmys[posId]; ok == false {
|
||||
this.stopInPosArmys[posId] = make(map[int]*model.Army)
|
||||
}
|
||||
this.stopInPosArmys[posId][army.Id] = army
|
||||
this.stop.Unlock()
|
||||
}
|
||||
|
||||
|
||||
func (this*armyLogic) addAction(t int64, army *model.Army) {
|
||||
this.endTime.Lock()
|
||||
defer this.endTime.Unlock()
|
||||
_, ok := this.endTimeArmys[t]
|
||||
if ok == false {
|
||||
this.endTimeArmys[t] = make([]*model.Army, 0)
|
||||
}
|
||||
this.endTimeArmys[t] = append(this.endTimeArmys[t], army)
|
||||
}
|
||||
|
||||
//把行动丢进来
|
||||
func (this*armyLogic) PushAction(army *model.Army) {
|
||||
|
||||
if army.Cmd == model.ArmyCmdAttack ||
|
||||
army.Cmd == model.ArmyCmdDefend ||
|
||||
army.Cmd == model.ArmyCmdTransfer{
|
||||
t := army.End.Unix()
|
||||
this.addAction(t, army)
|
||||
|
||||
}else if army.Cmd == model.ArmyCmdReclamation {
|
||||
if army.State == model.ArmyRunning {
|
||||
t := army.End.Unix()
|
||||
this.addAction(t, army)
|
||||
}else{
|
||||
costTime := static_conf.Basic.General.ReclamationTime
|
||||
t := army.End.Unix()+int64(costTime)
|
||||
this.addAction(t, army)
|
||||
}
|
||||
}else if army.Cmd == model.ArmyCmdBack {
|
||||
|
||||
if army.FromX == army.ToX && army.FromY == army.ToY {
|
||||
//处理调动到其他地方待命的情况,会归属的城池
|
||||
city, ok := mgr.RCMgr.Get(army.CityId)
|
||||
if ok {
|
||||
army.FromX = city.X
|
||||
army.FromY = city.Y
|
||||
|
||||
//计算回去的时间
|
||||
//speed := mgr.AMgr.GetSpeed(army)
|
||||
//t := mgr.TravelTime(speed, army.FromX, army.FromY, army.ToX, army.ToY)
|
||||
army.Start = time.Now()
|
||||
//army.End = time.Now().Add(time.Duration(t) * time.Millisecond)
|
||||
army.End = time.Now().Add(40*time.Second)
|
||||
}
|
||||
|
||||
}else{
|
||||
cur := time.Now()
|
||||
diff := army.End.Unix()-army.Start.Unix()
|
||||
if cur.Unix() < army.End.Unix(){
|
||||
diff = cur.Unix()-army.Start.Unix()
|
||||
}
|
||||
army.Start = cur
|
||||
army.End = cur.Add(time.Duration(diff) * time.Second)
|
||||
|
||||
}
|
||||
army.Cmd = model.ArmyCmdBack
|
||||
this.addAction(army.End.Unix(), army)
|
||||
}
|
||||
|
||||
this.Update(army)
|
||||
|
||||
}
|
||||
|
||||
func (this*armyLogic) ArmyBack(army *model.Army) {
|
||||
army.ClearConscript()
|
||||
|
||||
army.State = model.ArmyRunning
|
||||
army.Cmd = model.ArmyCmdBack
|
||||
|
||||
this.endTime.Lock()
|
||||
t := army.End.Unix()
|
||||
if actions, ok := this.endTimeArmys[t]; ok {
|
||||
for i, v := range actions {
|
||||
if v.Id == army.Id{
|
||||
actions = append(actions[:i], actions[i+1:]...)
|
||||
this.endTimeArmys[t] = actions
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
this.endTime.Unlock()
|
||||
this.PushAction(army)
|
||||
}
|
||||
|
||||
func (this*armyLogic) Reclamation(army *model.Army) {
|
||||
army.State = model.ArmyStop
|
||||
army.Cmd = model.ArmyCmdReclamation
|
||||
this.PushAction(army)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
575
server/slgserver/logic/army_war.go
Normal file
575
server/slgserver/logic/army_war.go
Normal file
@@ -0,0 +1,575 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"slgserver/server/slgserver/static_conf/general"
|
||||
"slgserver/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 战斗位置的属性
|
||||
type armyPosition struct {
|
||||
general *model.General
|
||||
soldiers int //兵力
|
||||
force int //武力
|
||||
strategy int //策略
|
||||
defense int //防御
|
||||
speed int //速度
|
||||
destroy int //破坏
|
||||
arms int //兵种
|
||||
position int //位置
|
||||
}
|
||||
|
||||
const maxRound = 10
|
||||
|
||||
type armyWar struct {
|
||||
attack *model.Army
|
||||
defense *model.Army
|
||||
attackPos []*armyPosition
|
||||
defensePos []*armyPosition
|
||||
}
|
||||
|
||||
type battle struct {
|
||||
AId int `json:"a_id"` //本回合发起攻击的武将id
|
||||
DId int `json:"d_id"` //本回合防御方的武将id
|
||||
ALoss int `json:"a_loss"` //本回合攻击方损失的兵力
|
||||
DLoss int `json:"d_loss"` //本回合防守方损失的兵力
|
||||
}
|
||||
|
||||
func (this *battle) to() []int {
|
||||
r := make([]int, 0)
|
||||
r = append(r, this.AId)
|
||||
r = append(r, this.DId)
|
||||
r = append(r, this.ALoss)
|
||||
r = append(r, this.DLoss)
|
||||
return r
|
||||
}
|
||||
|
||||
type warRound struct {
|
||||
Battle [][]int `json:"b"`
|
||||
}
|
||||
|
||||
type WarResult struct {
|
||||
round []*warRound
|
||||
result int //0失败,1平,2胜利
|
||||
}
|
||||
|
||||
func NewWar(attack *model.Army, defense *model.Army) *WarResult {
|
||||
|
||||
w := armyWar{attack: attack, defense: defense}
|
||||
w.init()
|
||||
wars := w.battle()
|
||||
|
||||
result := &WarResult{round: wars}
|
||||
if w.attackPos[0].soldiers == 0 {
|
||||
result.result = 0
|
||||
} else if w.defensePos[0] != nil && w.defensePos[0].soldiers != 0 {
|
||||
result.result = 1
|
||||
} else {
|
||||
result.result = 2
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 初始化军队和武将属性、兵种、加成等
|
||||
func (this *armyWar) init() {
|
||||
|
||||
//城内设施加成
|
||||
attackAdds := []int{0, 0, 0, 0}
|
||||
if this.attack.CityId > 0 {
|
||||
attackAdds = mgr.RFMgr.GetAdditions(this.attack.CityId,
|
||||
facility.TypeForce,
|
||||
facility.TypeDefense,
|
||||
facility.TypeSpeed,
|
||||
facility.TypeStrategy)
|
||||
}
|
||||
|
||||
defenseAdds := []int{0, 0, 0, 0}
|
||||
if this.defense.CityId > 0 {
|
||||
defenseAdds = mgr.RFMgr.GetAdditions(this.defense.CityId,
|
||||
facility.TypeForce,
|
||||
facility.TypeDefense,
|
||||
facility.TypeSpeed,
|
||||
facility.TypeStrategy)
|
||||
}
|
||||
|
||||
//阵营加成
|
||||
aCampAdds := []int{0}
|
||||
aCamp := this.attack.GetCamp()
|
||||
if aCamp > 0 {
|
||||
aCampAdds = mgr.RFMgr.GetAdditions(this.attack.CityId, facility.TypeHanAddition-1+aCamp)
|
||||
}
|
||||
|
||||
dCampAdds := []int{0}
|
||||
dCamp := this.attack.GetCamp()
|
||||
if dCamp > 0 {
|
||||
dCampAdds = mgr.RFMgr.GetAdditions(this.defense.CityId, facility.TypeHanAddition-1+aCamp)
|
||||
}
|
||||
|
||||
this.attackPos = make([]*armyPosition, 0)
|
||||
this.defensePos = make([]*armyPosition, 0)
|
||||
|
||||
for i, g := range this.attack.Gens {
|
||||
if g == nil {
|
||||
this.attackPos = append(this.attackPos, nil)
|
||||
} else {
|
||||
pos := &armyPosition{
|
||||
general: g,
|
||||
soldiers: this.attack.SoldierArray[i],
|
||||
force: g.GetForce() + attackAdds[0] + aCampAdds[0],
|
||||
defense: g.GetDefense() + attackAdds[1] + aCampAdds[0],
|
||||
speed: g.GetSpeed() + attackAdds[2] + aCampAdds[0],
|
||||
strategy: g.GetStrategy() + attackAdds[3] + aCampAdds[0],
|
||||
destroy: g.GetDestroy() + aCampAdds[0],
|
||||
arms: g.CurArms,
|
||||
position: i,
|
||||
}
|
||||
this.attackPos = append(this.attackPos, pos)
|
||||
}
|
||||
}
|
||||
|
||||
for i, g := range this.defense.Gens {
|
||||
if g == nil {
|
||||
this.defensePos = append(this.defensePos, nil)
|
||||
} else {
|
||||
pos := &armyPosition{
|
||||
general: g,
|
||||
soldiers: this.defense.SoldierArray[i],
|
||||
force: g.GetForce() + defenseAdds[0] + dCampAdds[0],
|
||||
defense: g.GetDefense() + defenseAdds[1] + dCampAdds[0],
|
||||
speed: g.GetSpeed() + defenseAdds[2] + dCampAdds[0],
|
||||
strategy: g.GetStrategy() + defenseAdds[3] + dCampAdds[0],
|
||||
destroy: g.GetDestroy() + dCampAdds[0],
|
||||
arms: g.CurArms,
|
||||
position: i,
|
||||
}
|
||||
this.defensePos = append(this.defensePos, pos)
|
||||
}
|
||||
}
|
||||
|
||||
slog.Debug("army defense positions initialized", "positions", this.defensePos)
|
||||
}
|
||||
|
||||
func (this *armyWar) battle() []*warRound {
|
||||
rounds := make([]*warRound, 0)
|
||||
cur := 0
|
||||
for true {
|
||||
r, isEnd := this.round()
|
||||
rounds = append(rounds, r)
|
||||
cur += 1
|
||||
if cur >= maxRound || isEnd {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
if this.attackPos[i] != nil {
|
||||
this.attack.SoldierArray[i] = this.attackPos[i].soldiers
|
||||
}
|
||||
if this.defensePos[i] != nil {
|
||||
this.defense.SoldierArray[i] = this.defensePos[i].soldiers
|
||||
}
|
||||
}
|
||||
|
||||
return rounds
|
||||
}
|
||||
|
||||
// 回合
|
||||
func (this *armyWar) round() (*warRound, bool) {
|
||||
|
||||
war := &warRound{}
|
||||
n := rand.Intn(10)
|
||||
attack := this.attackPos
|
||||
defense := this.defensePos
|
||||
|
||||
isEnd := false
|
||||
//随机先手
|
||||
if n%2 == 0 {
|
||||
attack = this.defensePos
|
||||
defense = this.attackPos
|
||||
}
|
||||
|
||||
for _, att := range attack {
|
||||
|
||||
////////攻击方begin//////////
|
||||
if att == nil || att.soldiers == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
def, _ := this.randArmyPosition(defense)
|
||||
if def == nil {
|
||||
isEnd = true
|
||||
goto end
|
||||
}
|
||||
|
||||
attHarmRatio := general.GenArms.GetHarmRatio(att.arms, def.arms)
|
||||
attHarm := float64(util.AbsInt(att.force-def.defense)*att.soldiers) * attHarmRatio * 0.0005
|
||||
attKill := int(attHarm)
|
||||
attKill = util.MinInt(attKill, def.soldiers)
|
||||
def.soldiers -= attKill
|
||||
att.general.Exp += attKill * 5
|
||||
|
||||
//大营干死了,直接结束
|
||||
if def.position == 0 && def.soldiers == 0 {
|
||||
isEnd = true
|
||||
goto end
|
||||
}
|
||||
////////攻击方end//////////
|
||||
|
||||
////////防守方begin//////////
|
||||
if def.soldiers == 0 || att.soldiers == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
defHarmRatio := general.GenArms.GetHarmRatio(def.arms, att.arms)
|
||||
defHarm := float64(util.AbsInt(def.force-att.defense)*def.soldiers) * defHarmRatio * 0.0005
|
||||
defKill := int(defHarm)
|
||||
|
||||
defKill = util.MinInt(defKill, att.soldiers)
|
||||
att.soldiers -= defKill
|
||||
def.general.Exp += defKill * 5
|
||||
|
||||
b := battle{AId: att.general.Id, ALoss: defKill, DId: def.general.Id, DLoss: attKill}
|
||||
war.Battle = append(war.Battle, b.to())
|
||||
|
||||
//大营干死了,直接结束
|
||||
if att.position == 0 && att.soldiers == 0 {
|
||||
isEnd = true
|
||||
goto end
|
||||
}
|
||||
////////防守方end//////////
|
||||
|
||||
}
|
||||
|
||||
end:
|
||||
return war, isEnd
|
||||
}
|
||||
|
||||
// 随机一个目标队伍
|
||||
func (this *armyWar) randArmyPosition(pos []*armyPosition) (*armyPosition, int) {
|
||||
isEmpty := true
|
||||
for _, v := range pos {
|
||||
if v != nil && v.soldiers != 0 {
|
||||
isEmpty = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if isEmpty {
|
||||
return nil, -1
|
||||
}
|
||||
|
||||
for true {
|
||||
r := rand.Intn(100)
|
||||
index := r % len(pos)
|
||||
if pos[index] != nil && pos[index].soldiers != 0 {
|
||||
return pos[index], index
|
||||
}
|
||||
}
|
||||
|
||||
return nil, -1
|
||||
}
|
||||
|
||||
func NewEmptyWar(attack *model.Army) *model.WarReport {
|
||||
//战报处理
|
||||
pArmy := attack.ToProto().(proto.Army)
|
||||
begArmy, _ := json.Marshal(pArmy)
|
||||
|
||||
//武将战斗前
|
||||
begGeneral := make([][]int, 0)
|
||||
for _, g := range attack.Gens {
|
||||
if g != nil {
|
||||
pg := g.ToProto().(proto.General)
|
||||
begGeneral = append(begGeneral, pg.ToArray())
|
||||
}
|
||||
}
|
||||
begGeneralData, _ := json.Marshal(begGeneral)
|
||||
|
||||
wr := &model.WarReport{X: attack.ToX, Y: attack.ToY, AttackRid: attack.RId,
|
||||
AttackIsRead: false, DefenseIsRead: true, DefenseRid: 0,
|
||||
BegAttackArmy: string(begArmy), BegDefenseArmy: "",
|
||||
EndAttackArmy: string(begArmy), EndDefenseArmy: "",
|
||||
BegAttackGeneral: string(begGeneralData),
|
||||
EndAttackGeneral: string(begGeneralData),
|
||||
BegDefenseGeneral: "",
|
||||
EndDefenseGeneral: "",
|
||||
Rounds: "",
|
||||
Result: 0,
|
||||
CTime: time.Now(),
|
||||
}
|
||||
return wr
|
||||
}
|
||||
|
||||
func checkCityOccupy(wr *model.WarReport, attackArmy *model.Army, city *model.MapRoleCity) {
|
||||
destory := mgr.GMgr.GetDestroy(attackArmy)
|
||||
wr.DestroyDurable = util.MinInt(destory, city.CurDurable)
|
||||
city.DurableChange(-destory)
|
||||
|
||||
if city.CurDurable == 0 {
|
||||
aAttr, _ := mgr.RAttrMgr.Get(attackArmy.RId)
|
||||
if aAttr.UnionId != 0 {
|
||||
//有联盟才能俘虏玩家
|
||||
wr.Occupy = 1
|
||||
dAttr, _ := mgr.RAttrMgr.Get(city.RId)
|
||||
dAttr.ParentId = aAttr.UnionId
|
||||
Union.PutChild(aAttr.UnionId, city.RId)
|
||||
dAttr.SyncExecute()
|
||||
city.OccupyTime = time.Now()
|
||||
} else {
|
||||
wr.Occupy = 0
|
||||
}
|
||||
} else {
|
||||
wr.Occupy = 0
|
||||
}
|
||||
city.SyncExecute()
|
||||
}
|
||||
|
||||
// 简单战斗
|
||||
func newBattle(attackArmy *model.Army) {
|
||||
city, ok := mgr.RCMgr.PositionCity(attackArmy.ToX, attackArmy.ToY)
|
||||
if ok {
|
||||
|
||||
//驻守队伍被打
|
||||
posId := global.ToPosition(attackArmy.ToX, attackArmy.ToY)
|
||||
enemys := ArmyLogic.GetStopArmys(posId)
|
||||
|
||||
//城内空闲的队伍被打
|
||||
if armys, ok := mgr.AMgr.GetByCity(city.CityId); ok {
|
||||
for _, enemy := range armys {
|
||||
if enemy.IsCanOutWar() {
|
||||
enemys = append(enemys, enemy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(enemys) == 0 {
|
||||
//没有队伍
|
||||
destory := mgr.GMgr.GetDestroy(attackArmy)
|
||||
city.DurableChange(-destory)
|
||||
city.SyncExecute()
|
||||
|
||||
wr := NewEmptyWar(attackArmy)
|
||||
wr.Result = 2
|
||||
wr.DefenseRid = city.RId
|
||||
wr.DefenseIsRead = false
|
||||
checkCityOccupy(wr, attackArmy, city)
|
||||
wr.SyncExecute()
|
||||
} else {
|
||||
lastWar, warReports := trigger(attackArmy, enemys, true)
|
||||
if lastWar.result > 1 {
|
||||
wr := warReports[len(warReports)-1]
|
||||
checkCityOccupy(wr, attackArmy, city)
|
||||
}
|
||||
for _, wr := range warReports {
|
||||
wr.SyncExecute()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//打建筑
|
||||
executeBuild(attackArmy)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func trigger(army *model.Army, enemys []*model.Army, isRoleEnemy bool) (*WarResult, []*model.WarReport) {
|
||||
|
||||
posId := global.ToPosition(army.ToX, army.ToY)
|
||||
warReports := make([]*model.WarReport, 0)
|
||||
var lastWar *WarResult = nil
|
||||
|
||||
for _, enemy := range enemys {
|
||||
//战报处理
|
||||
pArmy := army.ToProto().(proto.Army)
|
||||
pEnemy := enemy.ToProto().(proto.Army)
|
||||
|
||||
begArmy1, _ := json.Marshal(pArmy)
|
||||
begArmy2, _ := json.Marshal(pEnemy)
|
||||
|
||||
//武将战斗前
|
||||
begGeneral1 := make([][]int, 0)
|
||||
for _, g := range army.Gens {
|
||||
if g != nil {
|
||||
pg := g.ToProto().(proto.General)
|
||||
begGeneral1 = append(begGeneral1, pg.ToArray())
|
||||
}
|
||||
}
|
||||
begGeneralData1, _ := json.Marshal(begGeneral1)
|
||||
|
||||
begGeneral2 := make([][]int, 0)
|
||||
for _, g := range enemy.Gens {
|
||||
if g != nil {
|
||||
pg := g.ToProto().(proto.General)
|
||||
begGeneral2 = append(begGeneral2, pg.ToArray())
|
||||
}
|
||||
}
|
||||
begGeneralData2, _ := json.Marshal(begGeneral2)
|
||||
|
||||
lastWar = NewWar(army, enemy)
|
||||
|
||||
//武将战斗后
|
||||
endGeneral1 := make([][]int, 0)
|
||||
for _, g := range army.Gens {
|
||||
if g != nil {
|
||||
pg := g.ToProto().(proto.General)
|
||||
endGeneral1 = append(endGeneral1, pg.ToArray())
|
||||
level, exp := general.GenBasic.ExpToLevel(g.Exp)
|
||||
g.Level = level
|
||||
g.Exp = exp
|
||||
g.SyncExecute()
|
||||
}
|
||||
}
|
||||
endGeneralData1, _ := json.Marshal(endGeneral1)
|
||||
|
||||
endGeneral2 := make([][]int, 0)
|
||||
for _, g := range enemy.Gens {
|
||||
if g != nil {
|
||||
pg := g.ToProto().(proto.General)
|
||||
endGeneral2 = append(endGeneral2, pg.ToArray())
|
||||
level, exp := general.GenBasic.ExpToLevel(g.Exp)
|
||||
g.Level = level
|
||||
g.Exp = exp
|
||||
g.SyncExecute()
|
||||
}
|
||||
}
|
||||
endGeneralData2, _ := json.Marshal(endGeneral2)
|
||||
|
||||
pArmy = army.ToProto().(proto.Army)
|
||||
pEnemy = enemy.ToProto().(proto.Army)
|
||||
endArmy1, _ := json.Marshal(pArmy)
|
||||
endArmy2, _ := json.Marshal(pEnemy)
|
||||
|
||||
rounds, _ := json.Marshal(lastWar.round)
|
||||
wr := &model.WarReport{X: army.ToX, Y: army.ToY, AttackRid: army.RId,
|
||||
AttackIsRead: false, DefenseIsRead: false, DefenseRid: enemy.RId,
|
||||
BegAttackArmy: string(begArmy1), BegDefenseArmy: string(begArmy2),
|
||||
EndAttackArmy: string(endArmy1), EndDefenseArmy: string(endArmy2),
|
||||
BegAttackGeneral: string(begGeneralData1),
|
||||
BegDefenseGeneral: string(begGeneralData2),
|
||||
EndAttackGeneral: string(endGeneralData1),
|
||||
EndDefenseGeneral: string(endGeneralData2),
|
||||
Rounds: string(rounds),
|
||||
Result: lastWar.result,
|
||||
CTime: time.Now(),
|
||||
}
|
||||
|
||||
warReports = append(warReports, wr)
|
||||
enemy.ToSoldier()
|
||||
enemy.ToGeneral()
|
||||
|
||||
if isRoleEnemy {
|
||||
if lastWar.result > 1 {
|
||||
if isRoleEnemy {
|
||||
ArmyLogic.deleteStopArmy(posId)
|
||||
}
|
||||
ArmyLogic.ArmyBack(enemy)
|
||||
}
|
||||
enemy.SyncExecute()
|
||||
} else {
|
||||
wr.DefenseIsRead = true
|
||||
}
|
||||
}
|
||||
army.SyncExecute()
|
||||
return lastWar, warReports
|
||||
}
|
||||
|
||||
func executeBuild(army *model.Army) {
|
||||
roleBuild, _ := mgr.RBMgr.PositionBuild(army.ToX, army.ToY)
|
||||
|
||||
posId := global.ToPosition(army.ToX, army.ToY)
|
||||
posArmys := ArmyLogic.GetStopArmys(posId)
|
||||
isRoleEnemy := len(posArmys) != 0
|
||||
var enemys []*model.Army
|
||||
if isRoleEnemy == false {
|
||||
enemys = ArmyLogic.sys.GetArmy(army.ToX, army.ToY)
|
||||
} else {
|
||||
for _, v := range posArmys {
|
||||
enemys = append(enemys, v)
|
||||
}
|
||||
}
|
||||
|
||||
lastWar, warReports := trigger(army, enemys, isRoleEnemy)
|
||||
|
||||
if lastWar.result > 1 {
|
||||
if roleBuild != nil {
|
||||
destory := mgr.GMgr.GetDestroy(army)
|
||||
wr := warReports[len(warReports)-1]
|
||||
wr.DestroyDurable = util.MinInt(destory, roleBuild.CurDurable)
|
||||
roleBuild.CurDurable = util.MaxInt(0, roleBuild.CurDurable-destory)
|
||||
if roleBuild.CurDurable == 0 {
|
||||
//攻占了玩家的领地
|
||||
bLimit := static_conf.Basic.Role.BuildLimit
|
||||
if bLimit > mgr.RBMgr.BuildCnt(army.RId) {
|
||||
wr.Occupy = 1
|
||||
mgr.RBMgr.RemoveFromRole(roleBuild)
|
||||
mgr.RBMgr.AddBuild(army.RId, army.ToX, army.ToY)
|
||||
OccupyRoleBuild(army.RId, army.ToX, army.ToY)
|
||||
} else {
|
||||
wr.Occupy = 0
|
||||
}
|
||||
} else {
|
||||
wr.Occupy = 0
|
||||
}
|
||||
|
||||
} else {
|
||||
//占领系统领地
|
||||
wr := warReports[len(warReports)-1]
|
||||
blimit := static_conf.Basic.Role.BuildLimit
|
||||
if blimit > mgr.RBMgr.BuildCnt(army.RId) {
|
||||
OccupySystemBuild(army.RId, army.ToX, army.ToY)
|
||||
wr.DestroyDurable = 10000
|
||||
wr.Occupy = 1
|
||||
} else {
|
||||
wr.Occupy = 0
|
||||
}
|
||||
ArmyLogic.sys.DelArmy(army.ToX, army.ToY)
|
||||
}
|
||||
}
|
||||
|
||||
//领地发生变化
|
||||
if newRoleBuild, ok := mgr.RBMgr.PositionBuild(army.ToX, army.ToY); ok {
|
||||
newRoleBuild.SyncExecute()
|
||||
}
|
||||
|
||||
for _, wr := range warReports {
|
||||
wr.SyncExecute()
|
||||
}
|
||||
}
|
||||
|
||||
func OccupyRoleBuild(rid, x, y int) {
|
||||
newId := rid
|
||||
|
||||
if b, ok := mgr.RBMgr.PositionBuild(x, y); ok {
|
||||
|
||||
b.CurDurable = b.MaxDurable
|
||||
b.OccupyTime = time.Now()
|
||||
|
||||
oldId := b.RId
|
||||
slog.Info("battle in role build",
|
||||
"oldRId", oldId,
|
||||
"newRId", newId)
|
||||
b.RId = rid
|
||||
}
|
||||
}
|
||||
|
||||
func OccupySystemBuild(rid, x, y int) {
|
||||
|
||||
if _, ok := mgr.RBMgr.PositionBuild(x, y); ok {
|
||||
return
|
||||
}
|
||||
|
||||
if mgr.NMMgr.IsCanBuild(x, y) {
|
||||
rb, ok := mgr.RBMgr.AddBuild(rid, x, y)
|
||||
if ok {
|
||||
rb.OccupyTime = time.Now()
|
||||
}
|
||||
}
|
||||
}
|
||||
99
server/slgserver/logic/check_build.go
Normal file
99
server/slgserver/logic/check_build.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/util"
|
||||
)
|
||||
|
||||
//是否能到达
|
||||
func IsCanArrive(x, y, rid int) bool {
|
||||
var radius = 0
|
||||
unionId := getUnionId(rid)
|
||||
b, ok := mgr.RBMgr.PositionBuild(x, y)
|
||||
if ok {
|
||||
radius = b.CellRadius()
|
||||
}
|
||||
|
||||
c, ok := mgr.RCMgr.PositionCity(x, y)
|
||||
if ok {
|
||||
radius = c.CellRadius()
|
||||
}
|
||||
|
||||
//查找10格半径
|
||||
for tx := x-10; tx <= x+10; tx++ {
|
||||
for ty := y-10; ty <= y+10; ty++ {
|
||||
b1, ok := mgr.RBMgr.PositionBuild(tx, ty)
|
||||
if ok {
|
||||
absX := util.AbsInt(x-tx)
|
||||
absY := util.AbsInt(y-ty)
|
||||
if absX <= radius+b1.CellRadius()+1 && absY <= radius+b1.CellRadius()+1{
|
||||
unionId1 := getUnionId(b1.RId)
|
||||
parentId := getParentId(b1.RId)
|
||||
if b1.RId == rid || (unionId != 0 && (unionId == unionId1 || unionId == parentId)){
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c1, ok := mgr.RCMgr.PositionCity(tx, ty)
|
||||
if ok {
|
||||
absX := util.AbsInt(x-tx)
|
||||
absY := util.AbsInt(y-ty)
|
||||
if absX <= radius+c1.CellRadius()+1 && absY <= radius+c1.CellRadius()+1{
|
||||
unionId1 := getUnionId(c1.RId)
|
||||
parentId := getParentId(c1.RId)
|
||||
if c1.RId == rid || (unionId != 0 && (unionId == unionId1 || unionId == parentId)){
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsCanDefend(x, y, rid int) bool{
|
||||
unionId := getUnionId(rid)
|
||||
|
||||
b, ok := mgr.RBMgr.PositionBuild(x, y)
|
||||
if ok {
|
||||
tUnionId := getUnionId(b.RId)
|
||||
tParentId := getParentId(b.RId)
|
||||
if b.RId == rid{
|
||||
return true
|
||||
}else if tUnionId > 0 {
|
||||
return tUnionId == unionId
|
||||
}else if tParentId > 0 {
|
||||
return tParentId == unionId
|
||||
}
|
||||
}
|
||||
|
||||
c, ok := mgr.RCMgr.PositionCity(x, y)
|
||||
if ok {
|
||||
tUnionId := getUnionId(c.RId)
|
||||
tParentId := getParentId(c.RId)
|
||||
if c.RId == rid{
|
||||
return true
|
||||
}else if tUnionId > 0 {
|
||||
return tUnionId == unionId
|
||||
}else if tParentId > 0 {
|
||||
return tParentId == unionId
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//是否是免战
|
||||
func IsWarFree(x, y int) bool{
|
||||
b, ok := mgr.RBMgr.PositionBuild(x, y)
|
||||
if ok {
|
||||
return b.IsWarFree()
|
||||
}
|
||||
|
||||
c, ok := mgr.RCMgr.PositionCity(x, y)
|
||||
if ok && getParentId(c.RId) > 0 {
|
||||
return c.IsWarFree()
|
||||
}
|
||||
return false
|
||||
}
|
||||
169
server/slgserver/logic/coalition_logic.go
Normal file
169
server/slgserver/logic/coalition_logic.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func getUnionId(rid int) int {
|
||||
attr, ok := mgr.RAttrMgr.Get(rid)
|
||||
if ok {
|
||||
return attr.UnionId
|
||||
}else{
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func getUnionName(unionId int) string {
|
||||
if unionId <= 0{
|
||||
return ""
|
||||
}
|
||||
|
||||
u, ok := mgr.UnionMgr.Get(unionId)
|
||||
if ok {
|
||||
return u.Name
|
||||
}else{
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func getParentId(rid int) int {
|
||||
attr, ok := mgr.RAttrMgr.Get(rid)
|
||||
if ok {
|
||||
return attr.ParentId
|
||||
}else{
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func getMainMembers(unionId int) []int {
|
||||
u, ok := mgr.UnionMgr.Get(unionId)
|
||||
r := make([]int, 0)
|
||||
if ok {
|
||||
if u.Chairman != 0{
|
||||
r = append(r, u.Chairman)
|
||||
}
|
||||
if u.ViceChairman != 0{
|
||||
r = append(r, u.ViceChairman)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
type coalitionLogic struct {
|
||||
mutex sync.RWMutex
|
||||
children map[int]map[int]int //key:unionId,key&value:child rid
|
||||
}
|
||||
|
||||
func NewCoalitionLogic() *coalitionLogic {
|
||||
c := &coalitionLogic{
|
||||
children: make(map[int]map[int]int),
|
||||
}
|
||||
c.init()
|
||||
return c
|
||||
}
|
||||
|
||||
func (this*coalitionLogic) init() {
|
||||
//初始化下属玩家
|
||||
attrs := mgr.RAttrMgr.List()
|
||||
for _, attr := range attrs {
|
||||
if attr.ParentId !=0 {
|
||||
this.PutChild(attr.ParentId, attr.RId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*coalitionLogic) MemberEnter(rid, unionId int) {
|
||||
|
||||
attr, ok := mgr.RAttrMgr.TryCreate(rid)
|
||||
if ok {
|
||||
attr.UnionId = unionId
|
||||
if attr.ParentId == unionId{
|
||||
this.DelChild(unionId, attr.RId)
|
||||
}
|
||||
}else{
|
||||
slog.Warn("EnterUnion not found roleAttribute", "rid", rid)
|
||||
}
|
||||
|
||||
if rcs, ok := mgr.RCMgr.GetByRId(rid); ok {
|
||||
for _, rc := range rcs {
|
||||
rc.SyncExecute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*coalitionLogic) MemberExit(rid int) {
|
||||
|
||||
if ra, ok := mgr.RAttrMgr.Get(rid); ok {
|
||||
ra.UnionId = 0
|
||||
}
|
||||
|
||||
if rcs, ok := mgr.RCMgr.GetByRId(rid); ok {
|
||||
for _, rc := range rcs {
|
||||
rc.SyncExecute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//解散
|
||||
func (this*coalitionLogic) Dismiss(unionId int) {
|
||||
u, ok := mgr.UnionMgr.Get(unionId)
|
||||
if ok {
|
||||
mgr.UnionMgr.Remove(unionId)
|
||||
for _, rid := range u.MemberArray {
|
||||
this.MemberExit(rid)
|
||||
this.DelUnionAllChild(unionId)
|
||||
}
|
||||
u.State = model.UnionDismiss
|
||||
u.MemberArray = []int{}
|
||||
u.SyncExecute()
|
||||
}
|
||||
}
|
||||
|
||||
func (this*coalitionLogic) PutChild(unionId, rid int) {
|
||||
this.mutex.Lock()
|
||||
_, ok := this.children[unionId]
|
||||
if ok == false {
|
||||
this.children[unionId] = make(map[int]int)
|
||||
}
|
||||
this.children[unionId][rid] = rid
|
||||
this.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (this*coalitionLogic) DelChild(unionId, rid int) {
|
||||
this.mutex.Lock()
|
||||
children, ok := this.children[unionId]
|
||||
if ok {
|
||||
attr, ok := mgr.RAttrMgr.Get(rid)
|
||||
if ok {
|
||||
attr.ParentId = 0
|
||||
attr.SyncExecute()
|
||||
}
|
||||
delete(children, rid)
|
||||
}
|
||||
this.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (this*coalitionLogic) DelUnionAllChild(unionId int) {
|
||||
this.mutex.Lock()
|
||||
children, ok := this.children[unionId]
|
||||
if ok {
|
||||
for _, child := range children {
|
||||
attr, ok := mgr.RAttrMgr.Get(child)
|
||||
if ok {
|
||||
attr.ParentId = 0
|
||||
attr.SyncExecute()
|
||||
}
|
||||
|
||||
city, ok := mgr.RCMgr.GetMainCity(child)
|
||||
if ok {
|
||||
city.SyncExecute()
|
||||
}
|
||||
}
|
||||
delete(this.children, unionId)
|
||||
}
|
||||
this.mutex.Unlock()
|
||||
}
|
||||
65
server/slgserver/logic/init.go
Normal file
65
server/slgserver/logic/init.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
var Union *coalitionLogic
|
||||
var ArmyLogic *armyLogic
|
||||
|
||||
func BeforeInit() {
|
||||
//初始化一些方法
|
||||
model.ArmyIsInView = armyIsInView
|
||||
model.GetUnionId = getUnionId
|
||||
model.GetRoleNickName = mgr.RoleNickName
|
||||
model.GetParentId = getParentId
|
||||
model.GetMainMembers = getMainMembers
|
||||
model.GetUnionName = getUnionName
|
||||
model.GetYield = mgr.GetYield
|
||||
model.GetDepotCapacity = mgr.GetDepotCapacity
|
||||
model.GetCityCost = mgr.GetCityCost
|
||||
model.GetMaxDurable = mgr.GetMaxDurable
|
||||
model.GetCityLv = mgr.GetCityLV
|
||||
model.MapResTypeLevel = mgr.NMMgr.MapResTypeLevel
|
||||
}
|
||||
|
||||
//逻辑相关的初始化放在这里
|
||||
func Init() {
|
||||
|
||||
Union = NewCoalitionLogic()
|
||||
ArmyLogic = &armyLogic{
|
||||
arriveArmys: make(chan *model.Army, 100),
|
||||
interruptId: make(chan int, 100),
|
||||
giveUpId: make(chan int, 100),
|
||||
updateArmys: make(chan *model.Army, 100),
|
||||
outArmys: make(map[int]*model.Army),
|
||||
endTimeArmys: make(map[int64][]*model.Army),
|
||||
stopInPosArmys: make(map[int]map[int]*model.Army),
|
||||
passByPosArmys: make(map[int]map[int]*model.Army),
|
||||
sys: NewSysArmy()}
|
||||
|
||||
ArmyLogic.init()
|
||||
go ArmyLogic.check()
|
||||
go ArmyLogic.running()
|
||||
|
||||
}
|
||||
|
||||
func AfterInit() {
|
||||
go func() {
|
||||
for true {
|
||||
time.Sleep(1*time.Second)
|
||||
buildIds := mgr.RBMgr.CheckGiveUp()
|
||||
for _, buildId := range buildIds {
|
||||
ArmyLogic.GiveUp(buildId)
|
||||
}
|
||||
|
||||
buildIds = mgr.RBMgr.CheckDestroy()
|
||||
for _, buildId := range buildIds {
|
||||
ArmyLogic.Interrupt(buildId)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
286
server/slgserver/logic/mgr/army_mgr.go
Normal file
286
server/slgserver/logic/mgr/army_mgr.go
Normal file
@@ -0,0 +1,286 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
||||
type armyMgr struct {
|
||||
mutex sync.RWMutex
|
||||
armyById map[int]*model.Army //key:armyId
|
||||
armyByCityId map[int][]*model.Army //key:cityId
|
||||
armyByRId map[int][]*model.Army //key:rid
|
||||
}
|
||||
|
||||
var AMgr = &armyMgr{
|
||||
armyById: make(map[int]*model.Army),
|
||||
armyByCityId: make(map[int][]*model.Army),
|
||||
armyByRId: make(map[int][]*model.Army),
|
||||
}
|
||||
|
||||
func (this*armyMgr) Load() {
|
||||
|
||||
db.MasterDB.Table(model.Army{}).Find(this.armyById)
|
||||
|
||||
for _, army := range this.armyById {
|
||||
//处理征兵
|
||||
army.CheckConscript()
|
||||
cid := army.CityId
|
||||
c,ok:= this.armyByCityId[cid]
|
||||
if ok {
|
||||
this.armyByCityId[cid] = append(c, army)
|
||||
}else{
|
||||
this.armyByCityId[cid] = make([]*model.Army, 0)
|
||||
this.armyByCityId[cid] = append(this.armyByCityId[cid], army)
|
||||
}
|
||||
|
||||
//rid
|
||||
if _, ok := this.armyByRId[army.RId]; ok == false{
|
||||
this.armyByRId[army.RId] = make([]*model.Army, 0)
|
||||
}
|
||||
this.armyByRId[army.RId] = append(this.armyByRId[army.RId], army)
|
||||
this.updateGenerals(army)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this*armyMgr) insertOne(army *model.Army) {
|
||||
|
||||
aid := army.Id
|
||||
cid := army.CityId
|
||||
|
||||
this.armyById[aid] = army
|
||||
if _, r:= this.armyByCityId[cid]; r == false{
|
||||
this.armyByCityId[cid] = make([]*model.Army, 0)
|
||||
}
|
||||
this.armyByCityId[cid] = append(this.armyByCityId[cid], army)
|
||||
|
||||
if _, ok := this.armyByRId[army.RId]; ok == false{
|
||||
this.armyByRId[army.RId] = make([]*model.Army, 0)
|
||||
}
|
||||
this.armyByRId[army.RId] = append(this.armyByRId[army.RId], army)
|
||||
|
||||
this.updateGenerals(army)
|
||||
|
||||
}
|
||||
|
||||
func (this*armyMgr) insertMutil(armys []*model.Army) {
|
||||
for _, v := range armys {
|
||||
this.insertOne(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*armyMgr) Get(aid int) (*model.Army, bool){
|
||||
this.mutex.RLock()
|
||||
a, ok := this.armyById[aid]
|
||||
this.mutex.RUnlock()
|
||||
if ok {
|
||||
a.CheckConscript()
|
||||
return a, true
|
||||
}else{
|
||||
army := &model.Army{}
|
||||
ok, err := db.MasterDB.Table(model.Army{}).Where("id=?", aid).Get(army)
|
||||
if ok {
|
||||
this.mutex.Lock()
|
||||
this.insertOne(army)
|
||||
this.mutex.Unlock()
|
||||
return army, true
|
||||
}else{
|
||||
if err == nil{
|
||||
slog.Warn("armyMgr GetByRId armyId db not found",
|
||||
"armyId", aid)
|
||||
return nil, false
|
||||
}else{
|
||||
slog.Warn("armyMgr GetByRId db error", "armyId", aid)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*armyMgr) GetByCity(cid int) ([]*model.Army, bool){
|
||||
this.mutex.RLock()
|
||||
as, ok := this.armyByCityId[cid]
|
||||
this.mutex.RUnlock()
|
||||
if ok {
|
||||
for _, a := range as {
|
||||
a.CheckConscript()
|
||||
}
|
||||
return as, true
|
||||
}else{
|
||||
m := make([]*model.Army, 0)
|
||||
err := db.MasterDB.Table(model.Army{}).Where("cityId=?", cid).Find(&m)
|
||||
if err!=nil{
|
||||
slog.Warn("armyMgr GetByCity db error", "cityId", cid)
|
||||
return m, false
|
||||
}else{
|
||||
this.mutex.Lock()
|
||||
this.insertMutil(m)
|
||||
this.mutex.Unlock()
|
||||
return m, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*armyMgr) GetByCityOrder(cid int, order int8) (*model.Army, bool){
|
||||
rs, ok := this.GetByCity(cid)
|
||||
if ok {
|
||||
for _, r := range rs {
|
||||
if r.Order == order{
|
||||
return r, true
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return nil, false
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (this*armyMgr) GetByRId(rid int) ([]*model.Army, bool){
|
||||
this.mutex.RLock()
|
||||
as, ok := this.armyByRId[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
for _, a := range as {
|
||||
a.CheckConscript()
|
||||
}
|
||||
}
|
||||
return as, ok
|
||||
}
|
||||
|
||||
//归属于该位置的军队数量
|
||||
func (this*armyMgr) BelongPosArmyCnt(rid int, x, y int) int{
|
||||
cnt := 0
|
||||
armys, ok := this.GetByRId(rid)
|
||||
if ok {
|
||||
for _, army := range armys {
|
||||
if army.FromX == x && army.FromY == y{
|
||||
cnt += 1
|
||||
}else if army.Cmd == model.ArmyCmdTransfer && army.ToX == x && army.ToY == y {
|
||||
cnt += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cnt
|
||||
}
|
||||
|
||||
func (this*armyMgr) GetOrCreate(rid int, cid int, order int8) (*model.Army, error){
|
||||
|
||||
this.mutex.RLock()
|
||||
armys, ok := this.armyByCityId[cid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
for _, v := range armys {
|
||||
if v.Order == order{
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//需要创建
|
||||
army := &model.Army{RId: rid,
|
||||
Order: order,
|
||||
CityId: cid,
|
||||
Generals: `[0,0,0]`,
|
||||
Soldiers: `[0,0,0]`,
|
||||
GeneralArray: []int{0,0,0},
|
||||
SoldierArray: []int{0,0,0},
|
||||
ConscriptCnts: `[0,0,0]`,
|
||||
ConscriptTimes: `[0,0,0]`,
|
||||
ConscriptCntArray: []int{0,0,0},
|
||||
ConscriptTimeArray: []int64{0,0,0},
|
||||
}
|
||||
|
||||
city, ok := RCMgr.Get(cid)
|
||||
if ok {
|
||||
army.FromX = city.X
|
||||
army.FromY = city.Y
|
||||
army.ToX = city.X
|
||||
army.ToY = city.Y
|
||||
}
|
||||
|
||||
_, err := db.MasterDB.Insert(army)
|
||||
if err == nil{
|
||||
this.mutex.Lock()
|
||||
this.insertOne(army)
|
||||
this.mutex.Unlock()
|
||||
return army, nil
|
||||
}else{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (this*armyMgr) GetSpeed(army*model.Army) int{
|
||||
speed := 100000
|
||||
for _, g := range army.Gens {
|
||||
if g != nil {
|
||||
s := g.GetSpeed()
|
||||
if s < speed {
|
||||
speed = s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//阵营加成
|
||||
camp := army.GetCamp()
|
||||
campAdds := []int{0}
|
||||
if camp > 0{
|
||||
campAdds = RFMgr.GetAdditions(army.CityId, facility.TypeHanAddition-1+camp)
|
||||
}
|
||||
return speed + campAdds[0]
|
||||
}
|
||||
|
||||
//能否已经重复上阵了
|
||||
func (this*armyMgr) IsRepeat(rid int, cfgId int) bool{
|
||||
armys, ok := this.GetByRId(rid)
|
||||
if ok == false{
|
||||
return true
|
||||
}
|
||||
|
||||
for _, army := range armys {
|
||||
for _, g := range army.Gens {
|
||||
if g != nil {
|
||||
if g.CfgId == cfgId && g.CityId != 0{
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this*armyMgr) updateGenerals(armys... *model.Army) {
|
||||
for _, army := range armys {
|
||||
army.Gens = make([]*model.General, 0)
|
||||
for _, gid := range army.GeneralArray {
|
||||
if gid == 0{
|
||||
army.Gens = append(army.Gens, nil)
|
||||
}else{
|
||||
g, _ := GMgr.GetByGId(gid)
|
||||
army.Gens = append(army.Gens, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*armyMgr) All()[]*model.Army {
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
armys := make([]*model.Army, 0)
|
||||
for _, army := range this.armyById {
|
||||
armys = append(armys, army)
|
||||
}
|
||||
return armys
|
||||
}
|
||||
|
||||
326
server/slgserver/logic/mgr/city_facility_mgr.go
Normal file
326
server/slgserver/logic/mgr/city_facility_mgr.go
Normal file
@@ -0,0 +1,326 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var RFMgr = facilityMgr{
|
||||
facilities: make(map[int]*model.CityFacility),
|
||||
facilitiesByRId: make(map[int][]*model.CityFacility),
|
||||
}
|
||||
|
||||
type facilityMgr struct {
|
||||
mutex sync.RWMutex
|
||||
facilities map[int]*model.CityFacility
|
||||
facilitiesByRId map[int][]*model.CityFacility //key:rid
|
||||
}
|
||||
|
||||
func (this*facilityMgr) Load() {
|
||||
|
||||
err := db.MasterDB.Find(this.facilities)
|
||||
if err != nil {
|
||||
slog.Error("facilityMgr load city_facility table error")
|
||||
}
|
||||
|
||||
for _, cityFacility := range this.facilities {
|
||||
rid := cityFacility.RId
|
||||
_, ok := this.facilitiesByRId[rid]
|
||||
if ok == false {
|
||||
this.facilitiesByRId[rid] = make([]*model.CityFacility, 0)
|
||||
}
|
||||
this.facilitiesByRId[rid] = append(this.facilitiesByRId[rid], cityFacility)
|
||||
}
|
||||
|
||||
}
|
||||
func (this*facilityMgr) GetByRId(rid int) ([]*model.CityFacility, bool){
|
||||
this.mutex.RLock()
|
||||
r, ok := this.facilitiesByRId[rid]
|
||||
this.mutex.RUnlock()
|
||||
return r, ok
|
||||
}
|
||||
|
||||
func (this*facilityMgr) Get(cid int) (*model.CityFacility, bool){
|
||||
this.mutex.RLock()
|
||||
r, ok := this.facilities[cid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r, true
|
||||
}
|
||||
|
||||
r = &model.CityFacility{}
|
||||
ok, err := db.MasterDB.Table(r).Where("cityId=?", cid).Get(r)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
|
||||
if ok {
|
||||
this.mutex.Lock()
|
||||
this.facilities[cid] = r
|
||||
this.mutex.Unlock()
|
||||
return r, true
|
||||
}else{
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (this*facilityMgr) GetFacility(cid int, fType int8) (*model.Facility, bool){
|
||||
cf, ok := this.Get(cid)
|
||||
if ok == false{
|
||||
return nil, false
|
||||
}
|
||||
|
||||
facilities := cf.Facility()
|
||||
for _, v := range facilities {
|
||||
if v.Type == fType{
|
||||
return &v, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (this*facilityMgr) GetFacilityLv(cid int, fType int8) int8{
|
||||
f, ok := this.GetFacility(cid, fType)
|
||||
if ok {
|
||||
return f.GetLevel()
|
||||
}else{
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
获取城内设施加成
|
||||
*/
|
||||
func (this*facilityMgr) GetAdditions(cid int, additionType... int8 ) []int{
|
||||
cf, ok := this.Get(cid)
|
||||
ret := make([]int, len(additionType))
|
||||
if ok == false{
|
||||
return ret
|
||||
}
|
||||
|
||||
for i, at := range additionType {
|
||||
total := 0
|
||||
facilities := cf.Facility()
|
||||
for _, f := range facilities {
|
||||
if f.GetLevel() > 0{
|
||||
adds := facility.FConf.GetAdditions(f.Type)
|
||||
values := facility.FConf.GetValues(f.Type, f.GetLevel())
|
||||
|
||||
for i, add := range adds {
|
||||
if add == at {
|
||||
total += values[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret[i] = total
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
/*
|
||||
如果不存在尝试去创建
|
||||
*/
|
||||
func (this*facilityMgr) GetAndTryCreate(cid, rid int) (*model.CityFacility, bool){
|
||||
r, ok := this.Get(cid)
|
||||
if ok {
|
||||
return r, true
|
||||
}else{
|
||||
if _, ok:= RCMgr.Get(cid); ok {
|
||||
//创建
|
||||
fs := make([]model.Facility, len(facility.FConf.List))
|
||||
|
||||
for i, v := range facility.FConf.List {
|
||||
f := model.Facility{Type: v.Type, PrivateLevel: 0, Name: v.Name}
|
||||
fs[i] = f
|
||||
}
|
||||
|
||||
sdata, _ := json.Marshal(fs)
|
||||
cf := &model.CityFacility{CityId: cid, RId: rid, Facilities: string(sdata)}
|
||||
db.MasterDB.Table(cf).Insert(cf)
|
||||
|
||||
this.mutex.Lock()
|
||||
this.facilities[cid] = cf
|
||||
this.mutex.Unlock()
|
||||
|
||||
return cf, true
|
||||
}else{
|
||||
slog.Warn("cid not found", "cid", cid)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*facilityMgr) UpFacility(rid, cid int, fType int8) (*model.Facility, int){
|
||||
this.mutex.RLock()
|
||||
f, ok := this.facilities[cid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok == false{
|
||||
slog.Warn("UpFacility cityId not found",
|
||||
"cityId", cid,
|
||||
"type", int(fType))
|
||||
return nil, constant.CityNotExist
|
||||
}else{
|
||||
facilities := make([]*model.Facility, 0)
|
||||
var out *model.Facility
|
||||
json.Unmarshal([]byte(f.Facilities), &facilities)
|
||||
for _, fac := range facilities {
|
||||
if fac.Type == fType {
|
||||
maxLevel := facility.FConf.MaxLevel(fType)
|
||||
if fac.CanLV() == false {
|
||||
//正在升级中了
|
||||
slog.Warn("UpFacility error because already in up",
|
||||
"curLevel", int(fac.GetLevel()),
|
||||
"maxLevel", int(maxLevel),
|
||||
"cityId", cid,
|
||||
"type", int(fType))
|
||||
return nil, constant.UpError
|
||||
}else if fac.GetLevel() >= maxLevel {
|
||||
slog.Warn("UpFacility error",
|
||||
"curLevel", int(fac.GetLevel()),
|
||||
"maxLevel", int(maxLevel),
|
||||
"cityId", cid,
|
||||
"type", int(fType))
|
||||
return nil, constant.UpError
|
||||
}else{
|
||||
need, ok := facility.FConf.Need(fType, fac.GetLevel()+1)
|
||||
if ok == false {
|
||||
slog.Warn("UpFacility Need config error",
|
||||
"curLevel", int(fac.GetLevel()),
|
||||
"cityId", cid,
|
||||
"type", int(fType))
|
||||
return nil, constant.UpError
|
||||
}
|
||||
|
||||
code := RResMgr.TryUseNeed(rid, *need)
|
||||
if code == constant.OK {
|
||||
fac.UpTime = time.Now().Unix()
|
||||
out = fac
|
||||
if t, err := json.Marshal(facilities); err == nil{
|
||||
f.Facilities = string(t)
|
||||
f.SyncExecute()
|
||||
return out, constant.OK
|
||||
}else{
|
||||
return nil, constant.UpError
|
||||
}
|
||||
}else{
|
||||
slog.Warn("UpFacility Need Res Not Enough",
|
||||
"curLevel", int(fac.GetLevel()),
|
||||
"cityId", cid,
|
||||
"type", int(fType))
|
||||
return nil, code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slog.Warn("UpFacility error not found type",
|
||||
"cityId", cid,
|
||||
"type", int(fType))
|
||||
return nil, constant.UpError
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*facilityMgr) GetYield(rid int)model.Yield{
|
||||
cfs, ok := this.GetByRId(rid)
|
||||
var y model.Yield
|
||||
if ok {
|
||||
for _, cf := range cfs {
|
||||
for _, f := range cf.Facility() {
|
||||
if f.GetLevel() > 0{
|
||||
values := facility.FConf.GetValues(f.Type, f.GetLevel())
|
||||
additions := facility.FConf.GetAdditions(f.Type)
|
||||
for i, aType := range additions {
|
||||
if aType == facility.TypeWood {
|
||||
y.Wood += values[i]
|
||||
}else if aType == facility.TypeGrain {
|
||||
y.Grain += values[i]
|
||||
}else if aType == facility.TypeIron {
|
||||
y.Iron += values[i]
|
||||
}else if aType == facility.TypeStone {
|
||||
y.Stone += values[i]
|
||||
}else if aType == facility.TypeTax {
|
||||
y.Gold += values[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func (this*facilityMgr) GetDepotCapacity(rid int)int{
|
||||
cfs, ok := this.GetByRId(rid)
|
||||
limit := 0
|
||||
if ok {
|
||||
for _, cf := range cfs {
|
||||
for _, f := range cf.Facility() {
|
||||
if f.GetLevel() > 0{
|
||||
values := facility.FConf.GetValues(f.Type, f.GetLevel())
|
||||
additions := facility.FConf.GetAdditions(f.Type)
|
||||
for i, aType := range additions {
|
||||
if aType == facility.TypeWarehouseLimit {
|
||||
limit += values[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return limit
|
||||
}
|
||||
|
||||
func (this*facilityMgr) GetCost(cid int) int8{
|
||||
cf, ok := this.Get(cid)
|
||||
limit := 0
|
||||
if ok {
|
||||
for _, f := range cf.Facility() {
|
||||
if f.GetLevel() > 0{
|
||||
values := facility.FConf.GetValues(f.Type, f.GetLevel())
|
||||
additions := facility.FConf.GetAdditions(f.Type)
|
||||
for i, aType := range additions {
|
||||
if aType == facility.TypeCost {
|
||||
limit += values[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return int8(limit)
|
||||
}
|
||||
|
||||
func (this*facilityMgr) GetMaxDurable(cid int) int{
|
||||
cf, ok := this.Get(cid)
|
||||
limit := 0
|
||||
if ok {
|
||||
for _, f := range cf.Facility() {
|
||||
if f.GetLevel() > 0{
|
||||
values := facility.FConf.GetValues(f.Type, f.GetLevel())
|
||||
additions := facility.FConf.GetAdditions(f.Type)
|
||||
for i, aType := range additions {
|
||||
if aType == facility.TypeDurable {
|
||||
limit += values[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return limit
|
||||
}
|
||||
|
||||
func (this*facilityMgr) GetCityLV(cid int) int8{
|
||||
return this.GetFacilityLv(cid, facility.Main)
|
||||
}
|
||||
|
||||
|
||||
|
||||
98
server/slgserver/logic/mgr/coalition_mgr.go
Normal file
98
server/slgserver/logic/mgr/coalition_mgr.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type coalitionMgr struct {
|
||||
mutex sync.RWMutex
|
||||
unions map[int]*model.Coalition
|
||||
}
|
||||
|
||||
var UnionMgr = &coalitionMgr{
|
||||
unions: make(map[int]*model.Coalition),
|
||||
}
|
||||
|
||||
func (this*coalitionMgr) Load() {
|
||||
|
||||
rr := make([]*model.Coalition, 0)
|
||||
err := db.MasterDB.Where("state=?", model.UnionRunning).Find(&rr)
|
||||
if err != nil {
|
||||
slog.Error("coalitionMgr load union table error")
|
||||
}
|
||||
|
||||
for _, v := range rr {
|
||||
this.unions[v.Id] = v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*coalitionMgr) Get(unionId int) (*model.Coalition, bool){
|
||||
|
||||
this.mutex.RLock()
|
||||
r, ok := this.unions[unionId]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r, true
|
||||
}
|
||||
|
||||
m := &model.Coalition{}
|
||||
ok, err := db.MasterDB.Table(new(model.Coalition)).Where(
|
||||
"unionId=? and state=?", unionId, model.UnionRunning).Get(m)
|
||||
if ok {
|
||||
|
||||
this.mutex.Lock()
|
||||
this.unions[unionId] = m
|
||||
this.mutex.Unlock()
|
||||
|
||||
return m, true
|
||||
}else{
|
||||
if err == nil{
|
||||
slog.Warn("coalitionMgr not found", "unionId", unionId)
|
||||
return nil, false
|
||||
}else{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*coalitionMgr) Create(name string, rid int) (*model.Coalition, bool){
|
||||
m := &model.Coalition{Name: name, Ctime: time.Now(),
|
||||
CreateId: rid, Chairman: rid, State: model.UnionRunning, MemberArray: []int{rid}}
|
||||
|
||||
_, err := db.MasterDB.Table(new(model.Coalition)).InsertOne(m)
|
||||
if err == nil {
|
||||
|
||||
this.mutex.Lock()
|
||||
this.unions[m.Id] = m
|
||||
this.mutex.Unlock()
|
||||
|
||||
return m, true
|
||||
}else{
|
||||
slog.Error("db error", "error", err)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (this*coalitionMgr) List() []*model.Coalition {
|
||||
r := make([]*model.Coalition, 0)
|
||||
this.mutex.RLock()
|
||||
for _, coalition := range this.unions {
|
||||
r = append(r, coalition)
|
||||
}
|
||||
this.mutex.RUnlock()
|
||||
return r
|
||||
}
|
||||
|
||||
func (this*coalitionMgr) Remove(unionId int) {
|
||||
this.mutex.Lock()
|
||||
delete(this.unions, unionId)
|
||||
this.mutex.Unlock()
|
||||
}
|
||||
|
||||
353
server/slgserver/logic/mgr/general_mgr.go
Normal file
353
server/slgserver/logic/mgr/general_mgr.go
Normal file
@@ -0,0 +1,353 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/general"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type generalMgr struct {
|
||||
mutex sync.RWMutex
|
||||
genByRole map[int][]*model.General
|
||||
genByGId map[int]*model.General
|
||||
}
|
||||
|
||||
var GMgr = &generalMgr{
|
||||
genByRole: make(map[int][]*model.General),
|
||||
genByGId: make(map[int]*model.General),
|
||||
}
|
||||
|
||||
func (this*generalMgr) updatePhysicalPower() {
|
||||
limit := static_conf.Basic.General.PhysicalPowerLimit
|
||||
recoverCnt := static_conf.Basic.General.RecoveryPhysicalPower
|
||||
for true {
|
||||
time.Sleep(1*time.Hour)
|
||||
this.mutex.RLock()
|
||||
for _, g := range this.genByGId {
|
||||
if g.PhysicalPower < limit{
|
||||
g.PhysicalPower = util.MinInt(limit, g.PhysicalPower+recoverCnt)
|
||||
g.SyncExecute()
|
||||
}
|
||||
}
|
||||
this.mutex.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
//创建npc
|
||||
func (this*generalMgr) createNPC() ([]*model.General, bool){
|
||||
|
||||
gs := make([]*model.General, 0)
|
||||
sess := db.MasterDB.NewSession()
|
||||
sess.Begin()
|
||||
|
||||
for _, v := range general.General.GMap {
|
||||
if v.Star >= 3{
|
||||
arr := []int8{1,5,10,20}
|
||||
for _, level := range arr{
|
||||
r, ok := this.NewGeneral(v.CfgId, 0, level)
|
||||
if ok == false {
|
||||
sess.Rollback()
|
||||
return nil, false
|
||||
}
|
||||
gs = append(gs, r)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if err := sess.Commit(); err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
}else{
|
||||
return gs, true
|
||||
}
|
||||
}
|
||||
|
||||
func (this*generalMgr) add(g *model.General) {
|
||||
this.mutex.Lock()
|
||||
|
||||
if _,ok := this.genByRole[g.RId]; ok == false{
|
||||
this.genByRole[g.RId] = make([]*model.General, 0)
|
||||
}
|
||||
this.genByRole[g.RId] = append(this.genByRole[g.RId], g)
|
||||
this.genByGId[g.Id] = g
|
||||
|
||||
this.mutex.Unlock()
|
||||
}
|
||||
|
||||
|
||||
|
||||
func (this*generalMgr) Load(){
|
||||
|
||||
err := db.MasterDB.Table(model.General{}).Where("state=?",
|
||||
model.GeneralNormal).Find(this.genByGId)
|
||||
|
||||
if err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range this.genByGId {
|
||||
if _, ok := this.genByRole[v.RId]; ok==false {
|
||||
this.genByRole[v.RId] = make([]*model.General, 0)
|
||||
}
|
||||
this.genByRole[v.RId] = append(this.genByRole[v.RId], v)
|
||||
}
|
||||
|
||||
if len(this.genByGId) == 0{
|
||||
this.createNPC()
|
||||
}
|
||||
|
||||
go this.updatePhysicalPower()
|
||||
}
|
||||
|
||||
func (this*generalMgr) GetByRId(rid int) ([]*model.General, bool){
|
||||
this.mutex.Lock()
|
||||
r, ok := this.genByRole[rid]
|
||||
this.mutex.Unlock()
|
||||
|
||||
if ok {
|
||||
out := make([]*model.General, 0)
|
||||
for _, g := range r {
|
||||
if g.IsActive(){
|
||||
out = append(out, g)
|
||||
}
|
||||
}
|
||||
return out, true
|
||||
}
|
||||
|
||||
gs := make([]*model.General, 0)
|
||||
err := db.MasterDB.Table(new(model.General)).Where(
|
||||
"rid=? and state=?", rid, model.GeneralNormal).Find(&gs)
|
||||
|
||||
if err == nil {
|
||||
if len(gs) > 0 {
|
||||
for _, g := range gs {
|
||||
this.add(g)
|
||||
}
|
||||
return gs, true
|
||||
}else{
|
||||
slog.Warn("general not fount", "rid", rid)
|
||||
return nil, false
|
||||
}
|
||||
}else{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
//查找将领
|
||||
func (this*generalMgr) GetByGId(gid int) (*model.General, bool){
|
||||
this.mutex.RLock()
|
||||
g, ok := this.genByGId[gid]
|
||||
this.mutex.RUnlock()
|
||||
if ok {
|
||||
if g.IsActive(){
|
||||
return g, true
|
||||
}else{
|
||||
return nil, false
|
||||
}
|
||||
}else{
|
||||
|
||||
g := &model.General{}
|
||||
r, err := db.MasterDB.Table(new(model.General)).Where(
|
||||
"id=? and state=?", gid, model.GeneralNormal).Get(g)
|
||||
|
||||
if err == nil{
|
||||
if r {
|
||||
this.add(g)
|
||||
return g, true
|
||||
}else{
|
||||
slog.Warn("general gid not found", "gid", gid)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
}else{
|
||||
slog.Warn("general gid not found", "gid", gid)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//这个角色是否有这个武将
|
||||
func (this*generalMgr) HasGeneral(rid int ,gid int) (*model.General,bool){
|
||||
r, ok := this.GetByRId(rid)
|
||||
if ok {
|
||||
for _, v := range r {
|
||||
t := v
|
||||
if t.Id == gid {
|
||||
return t,true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil,false
|
||||
}
|
||||
|
||||
func (this*generalMgr) HasGenerals(rid int, gIds []int) ([]*model.General,bool){
|
||||
gs := make([]*model.General, 0)
|
||||
for i := 0; i < len(gIds); i++ {
|
||||
g,ok := this.HasGeneral(rid, gIds[i])
|
||||
if ok{
|
||||
gs = append(gs,g)
|
||||
}else{
|
||||
return gs,false
|
||||
}
|
||||
}
|
||||
return gs,true
|
||||
}
|
||||
|
||||
func (this*generalMgr) Count(rid int) int{
|
||||
gs, ok := this.GetByRId(rid)
|
||||
if ok {
|
||||
return len(gs)
|
||||
}else{
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (this*generalMgr) NewGeneral(cfgId int, rid int, level int8) (*model.General, bool) {
|
||||
g, ok := model.NewGeneral(cfgId, rid, level)
|
||||
if ok {
|
||||
this.add(g)
|
||||
}
|
||||
return g, ok
|
||||
}
|
||||
|
||||
/*
|
||||
如果不存在则去创建
|
||||
*/
|
||||
func (this*generalMgr) GetOrCreateByRId(rid int) ([]*model.General, bool){
|
||||
r, ok := this.GetByRId(rid)
|
||||
if ok {
|
||||
return r, true
|
||||
}else{
|
||||
//创建
|
||||
gs := make([]*model.General, 0)
|
||||
sess := db.MasterDB.NewSession()
|
||||
sess.Begin()
|
||||
|
||||
g, ok := this.RandCreateGeneral(rid,3)
|
||||
if ok == false{
|
||||
sess.Rollback()
|
||||
return nil, false
|
||||
}
|
||||
gs = g
|
||||
|
||||
if err := sess.Commit(); err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
}else{
|
||||
return gs, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
随机创建一个
|
||||
*/
|
||||
func (this*generalMgr) RandCreateGeneral(rid int, nums int) ([]*model.General, bool){
|
||||
gs := make([]*model.General, 0)
|
||||
sess := db.MasterDB.NewSession()
|
||||
sess.Begin()
|
||||
|
||||
for i := 0; i < nums; i++ {
|
||||
cfgId := general.General.Draw()
|
||||
g, ok := this.NewGeneral(cfgId, rid, 1)
|
||||
if ok == false{
|
||||
sess.Rollback()
|
||||
return nil, false
|
||||
}
|
||||
gs = append(gs, g)
|
||||
}
|
||||
|
||||
if err := sess.Commit(); err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
}else{
|
||||
return gs, true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//获取npc武将
|
||||
func (this*generalMgr) GetNPCGenerals(cnt int, star int8, level int8) ([]model.General, bool) {
|
||||
gs, ok := this.GetByRId(0)
|
||||
if ok == false {
|
||||
return make([]model.General, 0), false
|
||||
}else{
|
||||
target := make([]model.General, 0)
|
||||
for _, g := range gs {
|
||||
if g.Level == level && g.Star == star{
|
||||
target = append(target, *g)
|
||||
}
|
||||
}
|
||||
|
||||
if len(target) < cnt{
|
||||
return make([]model.General, 0), false
|
||||
}else{
|
||||
m := make(map[int]int)
|
||||
for true {
|
||||
r := rand.Intn(len(target))
|
||||
m[r] = r
|
||||
if len(m) == cnt{
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
rgs := make([]model.General, 0)
|
||||
for _, v := range m {
|
||||
t := target[v]
|
||||
rgs = append(rgs, t)
|
||||
}
|
||||
return rgs, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *generalMgr) GetDestroy(army *model.Army) int{
|
||||
destroy := 0
|
||||
for _, g := range army.Gens {
|
||||
if g != nil {
|
||||
destroy += g.GetDestroy()
|
||||
}
|
||||
}
|
||||
return destroy
|
||||
}
|
||||
|
||||
//体力是否足够
|
||||
func (this*generalMgr) PhysicalPowerIsEnough(army *model.Army, cost int) bool{
|
||||
for _, g := range army.Gens {
|
||||
if g == nil{
|
||||
continue
|
||||
}
|
||||
if g.PhysicalPower < cost{
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//尝试使用体力
|
||||
func (this *generalMgr) TryUsePhysicalPower(army *model.Army, cost int) bool{
|
||||
|
||||
if this.PhysicalPowerIsEnough(army, cost) == false{
|
||||
return false
|
||||
}
|
||||
|
||||
for _, g := range army.Gens {
|
||||
if g == nil{
|
||||
continue
|
||||
}
|
||||
g.PhysicalPower -= cost
|
||||
g.SyncExecute()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
176
server/slgserver/logic/mgr/national_map_mgr.go
Normal file
176
server/slgserver/logic/mgr/national_map_mgr.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"math"
|
||||
"os"
|
||||
"slgserver/config"
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const ScanWith = 3
|
||||
const ScanHeight = 3
|
||||
|
||||
type NMArray struct {
|
||||
arr []model.NationalMap
|
||||
}
|
||||
|
||||
type mapData struct {
|
||||
Width int `json:"w"`
|
||||
Height int `json:"h"`
|
||||
List [][]int `json:"list"`
|
||||
}
|
||||
|
||||
func Distance(begX, begY, endX, endY int) float64 {
|
||||
w := math.Abs(float64(endX - begX))
|
||||
h := math.Abs(float64(endY - begY))
|
||||
return math.Sqrt(w*w + h*h)
|
||||
}
|
||||
|
||||
func TravelTime(speed, begX, begY, endX, endY int) int {
|
||||
dis := Distance(begX, begY, endX, endY)
|
||||
t := dis / float64(speed) * 100000000
|
||||
return int(t)
|
||||
}
|
||||
|
||||
type NationalMapMgr struct {
|
||||
mutex sync.RWMutex
|
||||
conf map[int]model.NationalMap
|
||||
sysBuild map[int]model.NationalMap
|
||||
}
|
||||
|
||||
var NMMgr = &NationalMapMgr{
|
||||
conf: make(map[int]model.NationalMap),
|
||||
sysBuild: make(map[int]model.NationalMap),
|
||||
}
|
||||
|
||||
func (this *NationalMapMgr) Load() {
|
||||
|
||||
fileName := config.GetPath("logic.map_data",
|
||||
"data/conf/mapRes_0.json")
|
||||
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("NationalMapMgr load file error", "error", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
m := &mapData{}
|
||||
err = json.Unmarshal(jdata, m)
|
||||
if err != nil {
|
||||
slog.Error("NationalMapMgr Unmarshal json error", "error", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
//转成服务用的结构
|
||||
global.MapWith = m.Width
|
||||
global.MapHeight = m.Height
|
||||
|
||||
for i, v := range m.List {
|
||||
t := int8(v[0])
|
||||
l := int8(v[1])
|
||||
d := model.NationalMap{Y: i / global.MapHeight, X: i % global.MapWith, MId: i, Type: t, Level: l}
|
||||
this.conf[i] = d
|
||||
if d.Type == model.MapBuildSysCity ||
|
||||
d.Type == model.MapBuildSysFortress {
|
||||
this.sysBuild[i] = d
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("sysBuild len", "len", len(this.sysBuild))
|
||||
|
||||
}
|
||||
|
||||
func (this *NationalMapMgr) IsCanBuild(x, y int) bool {
|
||||
posIndex := global.ToPosition(x, y)
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
c, ok := this.conf[posIndex]
|
||||
if ok {
|
||||
if c.Type == 0 {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *NationalMapMgr) IsCanBuildCity(x, y int) bool {
|
||||
|
||||
//系统城池附近5格不能有玩家城池
|
||||
for _, nationalMap := range this.sysBuild {
|
||||
if nationalMap.Type == model.MapBuildSysCity {
|
||||
if x >= nationalMap.X-5 && x <= nationalMap.X+5 &&
|
||||
y >= nationalMap.Y-5 && y <= nationalMap.Y+5 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := x - 2; i <= x+2; i++ {
|
||||
if i < 0 || i > global.MapWith {
|
||||
return false
|
||||
}
|
||||
|
||||
for j := y - 2; j <= y+2; j++ {
|
||||
if j < 0 || j > global.MapHeight {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if this.IsCanBuild(x, y) == false ||
|
||||
RBMgr.IsEmpty(x, y) == false ||
|
||||
RCMgr.IsEmpty(x, y) == false {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *NationalMapMgr) MapResTypeLevel(x, y int) (bool, int8, int8) {
|
||||
n, ok := this.PositionBuild(x, y)
|
||||
if ok {
|
||||
return true, n.Type, n.Level
|
||||
}
|
||||
return false, 0, 0
|
||||
}
|
||||
|
||||
func (this *NationalMapMgr) PositionBuild(x, y int) (model.NationalMap, bool) {
|
||||
posIndex := global.ToPosition(x, y)
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
b, ok := this.conf[posIndex]
|
||||
return b, ok
|
||||
}
|
||||
|
||||
func (this *NationalMapMgr) Scan(x, y int) []model.NationalMap {
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
|
||||
minX := util.MaxInt(0, x-ScanWith)
|
||||
maxX := util.MinInt(40, x+ScanWith)
|
||||
|
||||
minY := util.MaxInt(0, y-ScanHeight)
|
||||
maxY := util.MinInt(40, y+ScanHeight)
|
||||
|
||||
c := (maxX - minX + 1) * (maxY - minY + 1)
|
||||
r := make([]model.NationalMap, c)
|
||||
|
||||
index := 0
|
||||
for i := minX; i <= maxX; i++ {
|
||||
for j := minY; j <= maxY; j++ {
|
||||
v, ok := this.conf[global.ToPosition(i, j)]
|
||||
if ok {
|
||||
r[index] = v
|
||||
}
|
||||
index++
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
121
server/slgserver/logic/mgr/role_attribute_mgr.go
Normal file
121
server/slgserver/logic/mgr/role_attribute_mgr.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type roleAttributeMgr struct {
|
||||
mutex sync.RWMutex
|
||||
attribute map[int]*model.RoleAttribute //key:rid
|
||||
}
|
||||
|
||||
var RAttrMgr = &roleAttributeMgr{
|
||||
attribute: make(map[int]*model.RoleAttribute),
|
||||
}
|
||||
|
||||
func (this*roleAttributeMgr) Load() {
|
||||
//加载
|
||||
t := make(map[int]*model.RoleAttribute)
|
||||
err := db.MasterDB.Find(t)
|
||||
if err != nil {
|
||||
slog.Error("roleAttributeMgr load role_attribute table error", "error", err)
|
||||
}
|
||||
|
||||
//获取联盟id
|
||||
for _, v:= range t {
|
||||
this.attribute[v.RId] = v
|
||||
}
|
||||
|
||||
l := UnionMgr.List()
|
||||
for _, c := range l {
|
||||
for _, rid := range c.MemberArray {
|
||||
attr, ok := this.attribute[rid]
|
||||
if ok {
|
||||
attr.UnionId = c.Id
|
||||
}else{
|
||||
attr := this.create(rid)
|
||||
if attr != nil{
|
||||
attr.UnionId = c.Id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*roleAttributeMgr) Get(rid int) (*model.RoleAttribute, bool){
|
||||
|
||||
this.mutex.RLock()
|
||||
r, ok := this.attribute[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r, true
|
||||
}else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (this*roleAttributeMgr) TryCreate(rid int) (*model.RoleAttribute, bool){
|
||||
attr, ok := this.Get(rid)
|
||||
if ok {
|
||||
return attr, true
|
||||
}else{
|
||||
this.mutex.Lock()
|
||||
defer this.mutex.Unlock()
|
||||
attr := this.create(rid)
|
||||
return attr, attr != nil
|
||||
}
|
||||
}
|
||||
|
||||
func (this*roleAttributeMgr) create(rid int) *model.RoleAttribute {
|
||||
roleAttr := &model.RoleAttribute{RId: rid, ParentId: 0, UnionId: 0}
|
||||
if _ , err := db.MasterDB.Insert(roleAttr); err != nil {
|
||||
slog.Error("insert RoleAttribute error", "error", err)
|
||||
return nil
|
||||
}else{
|
||||
this.attribute[rid] = roleAttr
|
||||
return roleAttr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*roleAttributeMgr) IsHasUnion(rid int) bool{
|
||||
|
||||
this.mutex.RLock()
|
||||
r, ok := this.attribute[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r.UnionId != 0
|
||||
}else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this*roleAttributeMgr) UnionId(rid int) int{
|
||||
|
||||
this.mutex.RLock()
|
||||
r, ok := this.attribute[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r.UnionId
|
||||
}else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (this*roleAttributeMgr) List() []*model.RoleAttribute {
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
ret := make([]*model.RoleAttribute, 0)
|
||||
for _, attribute := range this.attribute {
|
||||
ret = append(ret, attribute)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
436
server/slgserver/logic/mgr/role_build_mgr.go
Normal file
436
server/slgserver/logic/mgr/role_build_mgr.go
Normal file
@@ -0,0 +1,436 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type roleBuildMgr struct {
|
||||
baseMutex sync.RWMutex
|
||||
giveUpMutex sync.RWMutex
|
||||
destroyMutex sync.RWMutex
|
||||
dbRB map[int]*model.MapRoleBuild //key:dbId
|
||||
posRB map[int]*model.MapRoleBuild //key:posId
|
||||
roleRB map[int][]*model.MapRoleBuild //key:roleId
|
||||
giveUpRB map[int64]map[int]*model.MapRoleBuild //key:time
|
||||
destroyRB map[int64]map[int]*model.MapRoleBuild //key:time
|
||||
|
||||
}
|
||||
|
||||
var RBMgr = &roleBuildMgr{
|
||||
dbRB: make(map[int]*model.MapRoleBuild),
|
||||
posRB: make(map[int]*model.MapRoleBuild),
|
||||
roleRB: make(map[int][]*model.MapRoleBuild),
|
||||
giveUpRB: make(map[int64]map[int]*model.MapRoleBuild),
|
||||
destroyRB: make(map[int64]map[int]*model.MapRoleBuild),
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) Load() {
|
||||
|
||||
if total, err := db.MasterDB.Where("type = ? or type = ?",
|
||||
model.MapBuildSysCity,
|
||||
model.MapBuildSysFortress).Count(new(model.MapRoleBuild)); err != nil {
|
||||
slog.Error("db error when loading role build", "error", err)
|
||||
panic("db error: " + err.Error())
|
||||
} else {
|
||||
//初始化系统建筑到数据库
|
||||
if int64(len(NMMgr.sysBuild)) != total {
|
||||
db.MasterDB.Where("type = ? or type = ?",
|
||||
model.MapBuildSysCity,
|
||||
model.MapBuildSysFortress).Delete(new(model.MapRoleBuild))
|
||||
for _, sysBuild := range NMMgr.sysBuild {
|
||||
|
||||
build := model.MapRoleBuild{
|
||||
RId: 0,
|
||||
Type: sysBuild.Type,
|
||||
Level: sysBuild.Level,
|
||||
X: sysBuild.X,
|
||||
Y: sysBuild.Y,
|
||||
}
|
||||
build.Init()
|
||||
db.MasterDB.InsertOne(&build)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := db.MasterDB.Find(this.dbRB)
|
||||
if err != nil {
|
||||
slog.Error("roleBuildMgr load role_build table error", "error", err)
|
||||
}
|
||||
|
||||
curTime := time.Now().Unix()
|
||||
|
||||
//转成posRB 和 roleRB
|
||||
for _, v := range this.dbRB {
|
||||
v.Init()
|
||||
|
||||
//恢复正在放弃的土地
|
||||
if v.GiveUpTime != 0 {
|
||||
_, ok := this.giveUpRB[v.GiveUpTime]
|
||||
if ok == false {
|
||||
this.giveUpRB[v.GiveUpTime] = make(map[int]*model.MapRoleBuild)
|
||||
}
|
||||
this.giveUpRB[v.GiveUpTime][v.Id] = v
|
||||
}
|
||||
|
||||
//恢复正在拆除的建筑
|
||||
if v.OPLevel == 0 && v.Level != v.OPLevel {
|
||||
t := v.EndTime.Unix()
|
||||
if curTime >= t {
|
||||
v.ConvertToRes()
|
||||
} else {
|
||||
_, ok := this.destroyRB[t]
|
||||
if ok == false {
|
||||
this.destroyRB[t] = make(map[int]*model.MapRoleBuild)
|
||||
}
|
||||
this.destroyRB[t][v.Id] = v
|
||||
}
|
||||
}
|
||||
|
||||
posId := global.ToPosition(v.X, v.Y)
|
||||
this.posRB[posId] = v
|
||||
_, ok := this.roleRB[v.RId]
|
||||
if ok == false {
|
||||
this.roleRB[v.RId] = make([]*model.MapRoleBuild, 0)
|
||||
}
|
||||
this.roleRB[v.RId] = append(this.roleRB[v.RId], v)
|
||||
|
||||
//过滤掉到了放弃时间的领地
|
||||
if v.GiveUpTime != 0 && v.GiveUpTime <= curTime {
|
||||
this.RemoveFromRole(v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 检测正在放弃的土地是否到期了
|
||||
func (this *roleBuildMgr) CheckGiveUp() []int {
|
||||
var ret []int
|
||||
var builds []*model.MapRoleBuild
|
||||
|
||||
curTime := time.Now().Unix()
|
||||
this.giveUpMutex.Lock()
|
||||
for i := curTime - 10; i <= curTime; i++ {
|
||||
gs, ok := this.giveUpRB[i]
|
||||
if ok {
|
||||
for _, g := range gs {
|
||||
builds = append(builds, g)
|
||||
ret = append(ret, global.ToPosition(g.X, g.Y))
|
||||
}
|
||||
}
|
||||
}
|
||||
this.giveUpMutex.Unlock()
|
||||
|
||||
for _, build := range builds {
|
||||
this.RemoveFromRole(build)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// 检测正在拆除的建筑是否到期
|
||||
func (this *roleBuildMgr) CheckDestroy() []int {
|
||||
var ret []int
|
||||
var builds []*model.MapRoleBuild
|
||||
|
||||
curTime := time.Now().Unix()
|
||||
this.destroyMutex.Lock()
|
||||
for i := curTime - 10; i <= curTime; i++ {
|
||||
gs, ok := this.destroyRB[i]
|
||||
if ok {
|
||||
for _, g := range gs {
|
||||
builds = append(builds, g)
|
||||
ret = append(ret, global.ToPosition(g.X, g.Y))
|
||||
}
|
||||
}
|
||||
}
|
||||
this.destroyMutex.Unlock()
|
||||
|
||||
for _, build := range builds {
|
||||
build.ConvertToRes()
|
||||
build.SyncExecute()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
/*
|
||||
该位置是否被角色占领
|
||||
*/
|
||||
func (this *roleBuildMgr) IsEmpty(x, y int) bool {
|
||||
this.baseMutex.RLock()
|
||||
defer this.baseMutex.RUnlock()
|
||||
posId := global.ToPosition(x, y)
|
||||
_, ok := this.posRB[posId]
|
||||
return !ok
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) PositionBuild(x, y int) (*model.MapRoleBuild, bool) {
|
||||
this.baseMutex.RLock()
|
||||
defer this.baseMutex.RUnlock()
|
||||
posId := global.ToPosition(x, y)
|
||||
b, ok := this.posRB[posId]
|
||||
if ok {
|
||||
return b, ok
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) RoleFortressCnt(rid int) int {
|
||||
bs, ok := this.GetRoleBuild(rid)
|
||||
cnt := 0
|
||||
if ok == false {
|
||||
return 0
|
||||
} else {
|
||||
for _, b := range bs {
|
||||
if b.IsRoleFortress() {
|
||||
cnt += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) AddBuild(rid, x, y int) (*model.MapRoleBuild, bool) {
|
||||
|
||||
posId := global.ToPosition(x, y)
|
||||
this.baseMutex.Lock()
|
||||
rb, ok := this.posRB[posId]
|
||||
this.baseMutex.Unlock()
|
||||
if ok {
|
||||
rb.RId = rid
|
||||
this.baseMutex.Lock()
|
||||
if _, ok := this.roleRB[rid]; ok == false {
|
||||
this.roleRB[rid] = make([]*model.MapRoleBuild, 0)
|
||||
}
|
||||
this.roleRB[rid] = append(this.roleRB[rid], rb)
|
||||
this.baseMutex.Unlock()
|
||||
return rb, true
|
||||
|
||||
} else {
|
||||
|
||||
if b, ok := NMMgr.PositionBuild(x, y); ok {
|
||||
if cfg, _ := static_conf.MapBuildConf.BuildConfig(b.Type, b.Level); cfg != nil {
|
||||
rb := &model.MapRoleBuild{
|
||||
RId: rid, X: x, Y: y,
|
||||
Type: b.Type, Level: b.Level, OPLevel: b.Level,
|
||||
Name: cfg.Name, CurDurable: cfg.Durable,
|
||||
MaxDurable: cfg.Durable,
|
||||
}
|
||||
rb.Init()
|
||||
|
||||
if _, err := db.MasterDB.Table(model.MapRoleBuild{}).Insert(rb); err == nil {
|
||||
this.baseMutex.Lock()
|
||||
this.posRB[posId] = rb
|
||||
this.dbRB[rb.Id] = rb
|
||||
if _, ok := this.roleRB[rid]; ok == false {
|
||||
this.roleRB[rid] = make([]*model.MapRoleBuild, 0)
|
||||
}
|
||||
this.roleRB[rid] = append(this.roleRB[rid], rb)
|
||||
this.baseMutex.Unlock()
|
||||
return rb, true
|
||||
} else {
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) RemoveFromRole(build *model.MapRoleBuild) {
|
||||
this.baseMutex.Lock()
|
||||
rb, ok := this.roleRB[build.RId]
|
||||
if ok {
|
||||
for i, v := range rb {
|
||||
if v.Id == build.Id {
|
||||
this.roleRB[build.RId] = append(rb[:i], rb[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
this.baseMutex.Unlock()
|
||||
|
||||
//移除放弃事件
|
||||
t := build.GiveUpTime
|
||||
this.giveUpMutex.Lock()
|
||||
if ms, ok := this.giveUpRB[t]; ok {
|
||||
delete(ms, build.Id)
|
||||
}
|
||||
this.giveUpMutex.Unlock()
|
||||
|
||||
//移除拆除事件
|
||||
t = build.EndTime.Unix()
|
||||
this.destroyMutex.Lock()
|
||||
if ms, ok := this.destroyRB[t]; ok {
|
||||
delete(ms, build.Id)
|
||||
}
|
||||
this.destroyMutex.Unlock()
|
||||
|
||||
build.Reset()
|
||||
build.SyncExecute()
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) GetRoleBuild(rid int) ([]*model.MapRoleBuild, bool) {
|
||||
this.baseMutex.RLock()
|
||||
defer this.baseMutex.RUnlock()
|
||||
ra, ok := this.roleRB[rid]
|
||||
return ra, ok
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) BuildCnt(rid int) int {
|
||||
bs, ok := this.GetRoleBuild(rid)
|
||||
if ok {
|
||||
return len(bs)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) Scan(x, y int) []*model.MapRoleBuild {
|
||||
if x < 0 || x >= global.MapWith || y < 0 || y >= global.MapHeight {
|
||||
return nil
|
||||
}
|
||||
|
||||
this.baseMutex.RLock()
|
||||
defer this.baseMutex.RUnlock()
|
||||
|
||||
minX := util.MaxInt(0, x-ScanWith)
|
||||
maxX := util.MinInt(global.MapWith, x+ScanWith)
|
||||
minY := util.MaxInt(0, y-ScanHeight)
|
||||
maxY := util.MinInt(global.MapHeight, y+ScanHeight)
|
||||
|
||||
rb := make([]*model.MapRoleBuild, 0)
|
||||
for i := minX; i <= maxX; i++ {
|
||||
for j := minY; j <= maxY; j++ {
|
||||
posId := global.ToPosition(i, j)
|
||||
v, ok := this.posRB[posId]
|
||||
if ok && v.RId != 0 {
|
||||
rb = append(rb, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rb
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) ScanBlock(x, y, length int) []*model.MapRoleBuild {
|
||||
if x < 0 || x >= global.MapWith || y < 0 || y >= global.MapHeight {
|
||||
return nil
|
||||
}
|
||||
|
||||
this.baseMutex.RLock()
|
||||
defer this.baseMutex.RUnlock()
|
||||
|
||||
maxX := util.MinInt(global.MapWith, x+length-1)
|
||||
maxY := util.MinInt(global.MapHeight, y+length-1)
|
||||
|
||||
rb := make([]*model.MapRoleBuild, 0)
|
||||
for i := x; i <= maxX; i++ {
|
||||
for j := y; j <= maxY; j++ {
|
||||
posId := global.ToPosition(i, j)
|
||||
v, ok := this.posRB[posId]
|
||||
if ok && (v.RId != 0 || v.IsSysCity() || v.IsSysFortress()) {
|
||||
rb = append(rb, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rb
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) BuildIsRId(x, y, rid int) bool {
|
||||
b, ok := this.PositionBuild(x, y)
|
||||
if ok {
|
||||
return b.RId == rid
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) GetYield(rid int) model.Yield {
|
||||
builds, ok := this.GetRoleBuild(rid)
|
||||
var y model.Yield
|
||||
if ok {
|
||||
for _, b := range builds {
|
||||
y.Iron += b.Iron
|
||||
y.Wood += b.Wood
|
||||
y.Grain += b.Grain
|
||||
y.Stone += b.Grain
|
||||
}
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) GiveUp(x, y int) int {
|
||||
b, ok := this.PositionBuild(x, y)
|
||||
if ok == false {
|
||||
return constant.CannotGiveUp
|
||||
}
|
||||
|
||||
if b.IsWarFree() {
|
||||
return constant.BuildWarFree
|
||||
}
|
||||
|
||||
if b.GiveUpTime > 0 {
|
||||
return constant.BuildGiveUpAlready
|
||||
}
|
||||
|
||||
b.GiveUpTime = time.Now().Unix() + static_conf.Basic.Build.GiveUpTime
|
||||
b.SyncExecute()
|
||||
|
||||
this.giveUpMutex.Lock()
|
||||
_, ok = this.giveUpRB[b.GiveUpTime]
|
||||
if ok == false {
|
||||
this.giveUpRB[b.GiveUpTime] = make(map[int]*model.MapRoleBuild)
|
||||
}
|
||||
this.giveUpRB[b.GiveUpTime][b.Id] = b
|
||||
this.giveUpMutex.Unlock()
|
||||
|
||||
return constant.OK
|
||||
}
|
||||
|
||||
func (this *roleBuildMgr) Destroy(x, y int) int {
|
||||
|
||||
b, ok := this.PositionBuild(x, y)
|
||||
if ok == false {
|
||||
return constant.BuildNotMe
|
||||
}
|
||||
|
||||
if b.IsHaveModifyLVAuth() == false || b.IsInGiveUp() || b.IsBusy() {
|
||||
return constant.CanNotDestroy
|
||||
}
|
||||
|
||||
cfg, ok := static_conf.MapBCConf.BuildConfig(b.Type, b.Level)
|
||||
if ok == false {
|
||||
return constant.InvalidParam
|
||||
}
|
||||
|
||||
code := RResMgr.TryUseNeed(b.RId, cfg.Need)
|
||||
if code != constant.OK {
|
||||
return code
|
||||
}
|
||||
|
||||
b.EndTime = time.Now().Add(time.Duration(cfg.Time) * time.Second)
|
||||
this.destroyMutex.Lock()
|
||||
t := b.EndTime.Unix()
|
||||
_, ok = this.destroyRB[t]
|
||||
if ok == false {
|
||||
this.destroyRB[t] = make(map[int]*model.MapRoleBuild)
|
||||
}
|
||||
this.destroyRB[t][b.Id] = b
|
||||
this.destroyMutex.Unlock()
|
||||
|
||||
b.DelBuild(*cfg)
|
||||
b.SyncExecute()
|
||||
|
||||
return constant.OK
|
||||
}
|
||||
204
server/slgserver/logic/mgr/role_city_mgr.go
Normal file
204
server/slgserver/logic/mgr/role_city_mgr.go
Normal file
@@ -0,0 +1,204 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
type roleCityMgr struct {
|
||||
mutex sync.RWMutex
|
||||
dbCity map[int]*model.MapRoleCity //key: cid
|
||||
posCity map[int]*model.MapRoleCity //key: pos
|
||||
roleCity map[int][]*model.MapRoleCity //key: rid
|
||||
}
|
||||
|
||||
var RCMgr = &roleCityMgr{
|
||||
dbCity: make(map[int]*model.MapRoleCity),
|
||||
posCity: make(map[int]*model.MapRoleCity),
|
||||
roleCity: make(map[int][]*model.MapRoleCity),
|
||||
}
|
||||
|
||||
func GetCityCost(cid int) int8 {
|
||||
return RFMgr.GetCost(cid) + static_conf.Basic.City.Cost
|
||||
}
|
||||
|
||||
func GetMaxDurable(cid int) int {
|
||||
return RFMgr.GetMaxDurable(cid) + static_conf.Basic.City.Durable
|
||||
}
|
||||
|
||||
func GetCityLV(cid int) int8 {
|
||||
return RFMgr.GetCityLV(cid)
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) Load() {
|
||||
|
||||
err := db.MasterDB.Find(this.dbCity)
|
||||
if err != nil {
|
||||
slog.Error("roleCityMgr load role_city table error")
|
||||
}
|
||||
|
||||
//转成posCity、roleCity
|
||||
for _, v := range this.dbCity {
|
||||
posId := global.ToPosition(v.X, v.Y)
|
||||
this.posCity[posId] = v
|
||||
_, ok := this.roleCity[v.RId]
|
||||
if ok == false{
|
||||
this.roleCity[v.RId] = make([]*model.MapRoleCity, 0)
|
||||
}
|
||||
this.roleCity[v.RId] = append(this.roleCity[v.RId], v)
|
||||
}
|
||||
|
||||
go this.running()
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) running() {
|
||||
for true {
|
||||
t := static_conf.Basic.City.RecoveryTime
|
||||
time.Sleep(time.Duration(t) * time.Second)
|
||||
this.mutex.RLock()
|
||||
for _, city := range this.dbCity {
|
||||
if city.CurDurable < GetMaxDurable(city.CityId){
|
||||
city.DurableChange(100)
|
||||
city.SyncExecute()
|
||||
}
|
||||
}
|
||||
this.mutex.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
该位置是否被角色建立城池
|
||||
*/
|
||||
func (this*roleCityMgr) IsEmpty(x, y int) bool {
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
posId := global.ToPosition(x, y)
|
||||
_, ok := this.posCity[posId]
|
||||
return !ok
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) PositionCity(x, y int) (*model.MapRoleCity, bool) {
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
posId := global.ToPosition(x, y)
|
||||
c,ok := this.posCity[posId]
|
||||
return c, ok
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) Add(city *model.MapRoleCity) {
|
||||
|
||||
this.mutex.Lock()
|
||||
defer this.mutex.Unlock()
|
||||
this.dbCity[city.CityId] = city
|
||||
this.posCity[global.ToPosition(city.X, city.Y)] = city
|
||||
|
||||
_, ok := this.roleCity[city.RId]
|
||||
if ok == false{
|
||||
this.roleCity[city.RId] = make([]*model.MapRoleCity, 0)
|
||||
}
|
||||
this.roleCity[city.RId] = append(this.roleCity[city.RId], city)
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) Scan(x, y int) []*model.MapRoleCity {
|
||||
if x < 0 || x >= global.MapWith || y < 0 || y >= global.MapHeight {
|
||||
return nil
|
||||
}
|
||||
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
|
||||
minX := util.MaxInt(0, x-ScanWith)
|
||||
maxX := util.MinInt(40, x+ScanWith)
|
||||
minY := util.MaxInt(0, y-ScanHeight)
|
||||
maxY := util.MinInt(40, y+ScanHeight)
|
||||
|
||||
cb := make([]*model.MapRoleCity, 0)
|
||||
for i := minX; i <= maxX; i++ {
|
||||
for j := minY; j <= maxY; j++ {
|
||||
posId := global.ToPosition(i, j)
|
||||
v, ok := this.posCity[posId]
|
||||
if ok {
|
||||
cb = append(cb, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
return cb
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) ScanBlock(x, y, length int) []*model.MapRoleCity {
|
||||
if x < 0 || x >= global.MapWith || y < 0 || y >= global.MapHeight {
|
||||
return nil
|
||||
}
|
||||
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
|
||||
maxX := util.MinInt(global.MapWith, x+length-1)
|
||||
maxY := util.MinInt(global.MapHeight, y+length-1)
|
||||
|
||||
cb := make([]*model.MapRoleCity, 0)
|
||||
for i := x; i <= maxX; i++ {
|
||||
for j := y; j <= maxY; j++ {
|
||||
posId := global.ToPosition(i, j)
|
||||
v, ok := this.posCity[posId]
|
||||
if ok {
|
||||
cb = append(cb, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
return cb
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) GetByRId(rid int) ([]*model.MapRoleCity, bool){
|
||||
this.mutex.RLock()
|
||||
r, ok := this.roleCity[rid]
|
||||
this.mutex.RUnlock()
|
||||
return r, ok
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) GetMainCity(rid int) (*model.MapRoleCity, bool){
|
||||
citys, ok := this.GetByRId(rid)
|
||||
if ok == false {
|
||||
return nil, false
|
||||
}else{
|
||||
for _, city := range citys {
|
||||
if city.IsMain == 1{
|
||||
return city, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (this*roleCityMgr) Get(cid int) (*model.MapRoleCity, bool){
|
||||
this.mutex.RLock()
|
||||
r, ok := this.dbCity[cid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r, true
|
||||
}
|
||||
|
||||
|
||||
r = &model.MapRoleCity{}
|
||||
ok, err := db.MasterDB.Table(r).Where("cityId=?", cid).Get(r)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
|
||||
if ok {
|
||||
this.mutex.Lock()
|
||||
this.dbCity[cid] = r
|
||||
this.mutex.Unlock()
|
||||
return r, true
|
||||
}else{
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
48
server/slgserver/logic/mgr/role_mgr.go
Normal file
48
server/slgserver/logic/mgr/role_mgr.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func RoleNickName(rid int) string {
|
||||
vRole, ok := RMgr.Get(rid)
|
||||
if ok {
|
||||
return vRole.NickName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type roleMgr struct {
|
||||
mutex sync.RWMutex
|
||||
roles map[int]*model.Role
|
||||
}
|
||||
|
||||
var RMgr = &roleMgr{
|
||||
roles: make(map[int]*model.Role),
|
||||
}
|
||||
|
||||
func (this*roleMgr) Get(rid int) (*model.Role, bool){
|
||||
this.mutex.RLock()
|
||||
r, ok := this.roles[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r, true
|
||||
}
|
||||
|
||||
m := &model.Role{}
|
||||
ok, err := db.MasterDB.Table(new(model.Role)).Where("rid=?", rid).Get(m)
|
||||
if ok {
|
||||
this.mutex.Lock()
|
||||
this.roles[rid] = m
|
||||
this.mutex.Unlock()
|
||||
return m, true
|
||||
}else{
|
||||
slog.Warn("db error", "error", err, "rid", rid)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
248
server/slgserver/logic/mgr/role_res_mgr.go
Normal file
248
server/slgserver/logic/mgr/role_res_mgr.go
Normal file
@@ -0,0 +1,248 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type roleResMgr struct {
|
||||
mutex sync.RWMutex
|
||||
rolesRes map[int]*model.RoleRes
|
||||
}
|
||||
|
||||
var RResMgr = &roleResMgr{
|
||||
rolesRes: make(map[int]*model.RoleRes),
|
||||
}
|
||||
|
||||
//获取产量
|
||||
func GetYield(rid int) model.Yield {
|
||||
by := RBMgr.GetYield(rid)
|
||||
cy := RFMgr.GetYield(rid)
|
||||
var y model.Yield
|
||||
|
||||
y.Gold = by.Gold + cy.Gold + static_conf.Basic.Role.GoldYield
|
||||
y.Stone = by.Stone + cy.Stone + static_conf.Basic.Role.StoneYield
|
||||
y.Iron = by.Iron + cy.Iron + static_conf.Basic.Role.IronYield
|
||||
y.Grain = by.Grain + cy.Grain + static_conf.Basic.Role.GrainYield
|
||||
y.Wood = by.Wood + cy.Wood + static_conf.Basic.Role.WoodYield
|
||||
|
||||
return y
|
||||
}
|
||||
|
||||
//获取仓库容量
|
||||
func GetDepotCapacity(rid int) int {
|
||||
return RFMgr.GetDepotCapacity(rid) + static_conf.Basic.Role.DepotCapacity
|
||||
}
|
||||
|
||||
func (this*roleResMgr) Load() {
|
||||
|
||||
rr := make([]*model.RoleRes, 0)
|
||||
err := db.MasterDB.Find(&rr)
|
||||
if err != nil {
|
||||
slog.Error("roleResMgr load role_res table error")
|
||||
}
|
||||
|
||||
for _, v := range rr {
|
||||
this.rolesRes[v.RId] = v
|
||||
}
|
||||
|
||||
go this.produce()
|
||||
|
||||
}
|
||||
|
||||
|
||||
func (this*roleResMgr) Get(rid int) (*model.RoleRes, bool){
|
||||
|
||||
this.mutex.RLock()
|
||||
r, ok := this.rolesRes[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r, true
|
||||
}
|
||||
|
||||
m := &model.RoleRes{}
|
||||
ok, err := db.MasterDB.Table(new(model.RoleRes)).Where("rid=?", rid).Get(m)
|
||||
if ok {
|
||||
|
||||
this.mutex.Lock()
|
||||
this.rolesRes[rid] = m
|
||||
this.mutex.Unlock()
|
||||
|
||||
return m, true
|
||||
}else{
|
||||
if err == nil{
|
||||
slog.Warn("RoleRes not found", "rid", rid)
|
||||
return nil, false
|
||||
}else{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*roleResMgr) Add(res *model.RoleRes) (){
|
||||
|
||||
this.mutex.Lock()
|
||||
this.rolesRes[res.RId] = res
|
||||
this.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (this*roleResMgr) TryUseNeed(rid int, need facility.NeedRes) int{
|
||||
|
||||
this.mutex.RLock()
|
||||
rr, ok := this.rolesRes[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
if need.Decree <= rr.Decree && need.Grain <= rr.Grain &&
|
||||
need.Stone <= rr.Stone && need.Wood <= rr.Wood &&
|
||||
need.Iron <= rr.Iron && need.Gold <= rr.Gold {
|
||||
rr.Decree -= need.Decree
|
||||
rr.Iron -= need.Iron
|
||||
rr.Wood -= need.Wood
|
||||
rr.Stone -= need.Stone
|
||||
rr.Grain -= need.Grain
|
||||
rr.Gold -= need.Gold
|
||||
|
||||
rr.SyncExecute()
|
||||
return constant.OK
|
||||
}else{
|
||||
if need.Decree > rr.Decree{
|
||||
return constant.DecreeNotEnough
|
||||
}else{
|
||||
return constant.ResNotEnough
|
||||
}
|
||||
}
|
||||
}else {
|
||||
return constant.RoleNotExist
|
||||
}
|
||||
}
|
||||
|
||||
//政令是否足够
|
||||
func (this*roleResMgr) DecreeIsEnough(rid int, cost int) bool {
|
||||
|
||||
this.mutex.RLock()
|
||||
rr, ok := this.rolesRes[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
if rr.Decree >= cost {
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this*roleResMgr) TryUseDecree(rid int, decree int) bool{
|
||||
|
||||
this.mutex.RLock()
|
||||
rr, ok := this.rolesRes[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
if rr.Decree >= decree {
|
||||
rr.Decree -= decree
|
||||
rr.SyncExecute()
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//金币是否足够
|
||||
func (this*roleResMgr) GoldIsEnough(rid int, cost int) bool {
|
||||
|
||||
this.mutex.RLock()
|
||||
rr, ok := this.rolesRes[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
if rr.Gold >= cost {
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*roleResMgr) TryUseGold(rid int, gold int) bool{
|
||||
|
||||
this.mutex.RLock()
|
||||
rr, ok := this.rolesRes[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
if rr.Gold >= gold {
|
||||
rr.Gold -= gold
|
||||
rr.SyncExecute()
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*roleResMgr) produce() {
|
||||
index := 1
|
||||
for true {
|
||||
t := static_conf.Basic.Role.RecoveryTime
|
||||
time.Sleep(time.Duration(t) * time.Second)
|
||||
this.mutex.RLock()
|
||||
for _, v := range this.rolesRes {
|
||||
//加判断是因为爆仓了,资源不无故减少
|
||||
capacity := GetDepotCapacity(v.RId)
|
||||
yield := GetYield(v.RId)
|
||||
if v.Wood < capacity{
|
||||
v.Wood += util.MinInt(yield.Wood/6, capacity)
|
||||
}
|
||||
|
||||
if v.Iron < capacity{
|
||||
v.Iron += util.MinInt(yield.Iron/6, capacity)
|
||||
}
|
||||
|
||||
if v.Stone < capacity{
|
||||
v.Stone += util.MinInt(yield.Stone/6, capacity)
|
||||
}
|
||||
|
||||
if v.Grain < capacity{
|
||||
v.Grain += util.MinInt(yield.Grain/6, capacity)
|
||||
}
|
||||
|
||||
if v.Gold < capacity{
|
||||
v.Grain += util.MinInt(yield.Grain/6, capacity)
|
||||
}
|
||||
|
||||
if index%6 == 0{
|
||||
if v.Decree < static_conf.Basic.Role.DecreeLimit{
|
||||
v.Decree+=1
|
||||
}
|
||||
}
|
||||
v.SyncExecute()
|
||||
}
|
||||
index++
|
||||
this.mutex.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
97
server/slgserver/logic/mgr/skill_mgr.go
Normal file
97
server/slgserver/logic/mgr/skill_mgr.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package mgr
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/model"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type skillMgr struct {
|
||||
mutex sync.RWMutex
|
||||
skillMap map[int][]*model.Skill
|
||||
}
|
||||
|
||||
var SkillMgr = &skillMgr{
|
||||
skillMap: make(map[int][]*model.Skill),
|
||||
}
|
||||
|
||||
|
||||
func (this*skillMgr) Load() {
|
||||
|
||||
rr := make([]*model.Skill, 0)
|
||||
err := db.MasterDB.Find(&rr)
|
||||
if err != nil {
|
||||
slog.Error("skillMgr load role_res table error")
|
||||
}
|
||||
|
||||
for _, v := range rr {
|
||||
if this.skillMap[v.RId] == nil{
|
||||
this.skillMap[v.RId] = make([]*model.Skill, 0)
|
||||
}
|
||||
this.skillMap[v.RId] = append(this.skillMap[v.RId], v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this*skillMgr) Get(rid int) ([]*model.Skill, bool){
|
||||
|
||||
this.mutex.RLock()
|
||||
r, ok := this.skillMap[rid]
|
||||
this.mutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return r, true
|
||||
}
|
||||
|
||||
m := make([]*model.Skill, 0)
|
||||
ok, err := db.MasterDB.Table(new(model.Skill)).Where("rid=?", rid).Get(&m)
|
||||
if ok {
|
||||
|
||||
this.mutex.Lock()
|
||||
this.skillMap[rid] = m
|
||||
this.mutex.Unlock()
|
||||
|
||||
return m, true
|
||||
}else{
|
||||
if err == nil{
|
||||
slog.Warn("skill not found", "rid", rid)
|
||||
return nil, false
|
||||
}else{
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*skillMgr) GetSkillOrCreate(rid int, cfg int) (*model.Skill, bool){
|
||||
|
||||
success := true
|
||||
m, ok := this.Get(rid)
|
||||
var ret *model.Skill = nil
|
||||
if ok {
|
||||
for _, v := range m {
|
||||
if v.CfgId != cfg{
|
||||
continue
|
||||
}else{
|
||||
ret = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ret == nil {
|
||||
ret = model.NewSkill(rid, cfg)
|
||||
_, err := db.MasterDB.InsertOne(ret)
|
||||
if err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
success = false
|
||||
}else{
|
||||
if this.skillMap[rid] == nil{
|
||||
this.skillMap[rid] = make([]*model.Skill, 0)
|
||||
}
|
||||
this.skillMap[rid] = append(this.skillMap[rid], ret)
|
||||
}
|
||||
}
|
||||
return ret, success
|
||||
|
||||
}
|
||||
95
server/slgserver/logic/sys_army_logic.go
Normal file
95
server/slgserver/logic/sys_army_logic.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
||||
func NewSysArmy() *sysArmyLogic {
|
||||
return &sysArmyLogic{
|
||||
sysArmys: make(map[int][]*model.Army),
|
||||
}
|
||||
}
|
||||
|
||||
type sysArmyLogic struct {
|
||||
mutex sync.Mutex
|
||||
sysArmys map[int][]*model.Army //key:posId 系统建筑军队
|
||||
}
|
||||
|
||||
func (this* sysArmyLogic) getArmyCfg(x, y int) (star int8, lv int8, soilders int) {
|
||||
defender := 1
|
||||
star = 3
|
||||
lv = 5
|
||||
soilders = 100
|
||||
|
||||
if mapBuild, ok := mgr.NMMgr.PositionBuild(x, y); ok{
|
||||
cfg, ok := static_conf.MapBuildConf.BuildConfig(mapBuild.Type, mapBuild.Level)
|
||||
if ok {
|
||||
defender = cfg.Defender
|
||||
if npc, ok := static_conf.Basic.GetNPC(cfg.Level); ok {
|
||||
soilders = npc.Soilders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if defender == 1{
|
||||
star = 3
|
||||
lv = 5
|
||||
}else if defender == 2{
|
||||
star = 4
|
||||
lv = 10
|
||||
}else {
|
||||
star = 5
|
||||
lv = 20
|
||||
}
|
||||
|
||||
return star, lv, soilders
|
||||
}
|
||||
|
||||
func (this *sysArmyLogic) GetArmy(x, y int) []*model.Army {
|
||||
posId := global.ToPosition(x, y)
|
||||
this.mutex.Lock()
|
||||
a, ok := this.sysArmys[posId]
|
||||
this.mutex.Unlock()
|
||||
if ok {
|
||||
return a
|
||||
}else{
|
||||
armys := make([]*model.Army, 0)
|
||||
|
||||
star, lv, soilders := this.getArmyCfg(x, y)
|
||||
out, ok := mgr.GMgr.GetNPCGenerals(3, star, lv)
|
||||
if ok {
|
||||
gsId := make([]int, 0)
|
||||
gs := make([]*model.General, 3)
|
||||
|
||||
for i := 0; i < len(out) ; i++ {
|
||||
gs[i] = &out[i]
|
||||
}
|
||||
|
||||
scnt := []int{soilders, soilders, soilders}
|
||||
army := &model.Army{RId: 0, Order: 0, CityId: 0,
|
||||
GeneralArray: gsId, Gens: gs, SoldierArray: scnt}
|
||||
army.ToGeneral()
|
||||
army.ToSoldier()
|
||||
|
||||
armys = append(armys, army)
|
||||
posId := global.ToPosition(x, y)
|
||||
this.sysArmys[posId] = armys
|
||||
}
|
||||
|
||||
return armys
|
||||
}
|
||||
}
|
||||
|
||||
func (this *sysArmyLogic) DelArmy(x, y int) {
|
||||
this.mutex.Lock()
|
||||
defer this.mutex.Unlock()
|
||||
posId := global.ToPosition(x, y)
|
||||
delete(this.sysArmys, posId)
|
||||
}
|
||||
|
||||
|
||||
36
server/slgserver/logic/view.go
Normal file
36
server/slgserver/logic/view.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/util"
|
||||
)
|
||||
|
||||
var ViewWidth = 5
|
||||
var ViewHeight = 5
|
||||
|
||||
//是否在视野范围内
|
||||
func armyIsInView(rid, x, y int) bool {
|
||||
unionId := getUnionId(rid)
|
||||
for i := util.MaxInt(x-ViewWidth, 0); i < util.MinInt(x+ViewWidth, global.MapWith) ; i++ {
|
||||
for j := util.MaxInt(y-ViewHeight, 0); j < util.MinInt(y+ViewHeight, global.MapHeight) ; j++ {
|
||||
build, ok := mgr.RBMgr.PositionBuild(i, j)
|
||||
if ok {
|
||||
tUnionId := getUnionId(build.RId)
|
||||
if (tUnionId != 0 && unionId == tUnionId) || build.RId == rid{
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
city, ok := mgr.RCMgr.PositionCity(i, j)
|
||||
if ok {
|
||||
tUnionId := getUnionId(city.RId)
|
||||
if (tUnionId != 0 && unionId == tUnionId) || city.RId == rid{
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
338
server/slgserver/model/army.go
Normal file
338
server/slgserver/model/army.go
Normal file
@@ -0,0 +1,338 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/global"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/util"
|
||||
"time"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
const (
|
||||
ArmyCmdIdle = 0 //空闲
|
||||
ArmyCmdAttack = 1 //攻击
|
||||
ArmyCmdDefend = 2 //驻守
|
||||
ArmyCmdReclamation = 3 //屯垦
|
||||
ArmyCmdBack = 4 //撤退
|
||||
ArmyCmdConscript = 5 //征兵
|
||||
ArmyCmdTransfer = 6 //调动
|
||||
)
|
||||
|
||||
const (
|
||||
ArmyStop = 0
|
||||
ArmyRunning = 1
|
||||
)
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbArmyMgr *armyDBMgr
|
||||
|
||||
func init() {
|
||||
dbArmyMgr = &armyDBMgr{armys: make(chan *Army, 100)}
|
||||
go dbArmyMgr.running()
|
||||
}
|
||||
|
||||
type armyDBMgr struct {
|
||||
armys chan *Army
|
||||
}
|
||||
|
||||
func (this *armyDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case army := <-this.armys:
|
||||
if army.Id > 0 {
|
||||
_, err := db.MasterDB.Table(army).ID(army.Id).Cols(
|
||||
"soldiers", "generals", "conscript_times",
|
||||
"conscript_cnts", "cmd", "from_x", "from_y", "to_x",
|
||||
"to_y", "start", "end").Update(army)
|
||||
if err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
} else {
|
||||
slog.Warn("update army fail, because id <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *armyDBMgr) push(army *Army) {
|
||||
this.armys <- army
|
||||
}
|
||||
|
||||
/*******db 操作end********/
|
||||
|
||||
// 军队
|
||||
type Army struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
CityId int `xorm:"cityId"`
|
||||
Order int8 `xorm:"order"`
|
||||
Generals string `xorm:"generals"`
|
||||
Soldiers string `xorm:"soldiers"`
|
||||
ConscriptTimes string `xorm:"conscript_times"` //征兵结束时间,json数组
|
||||
ConscriptCnts string `xorm:"conscript_cnts"` //征兵数量,json数组
|
||||
Cmd int8 `xorm:"cmd"`
|
||||
FromX int `xorm:"from_x"`
|
||||
FromY int `xorm:"from_y"`
|
||||
ToX int `xorm:"to_x"`
|
||||
ToY int `xorm:"to_y"`
|
||||
Start time.Time `json:"-"xorm:"start"`
|
||||
End time.Time `json:"-"xorm:"end"`
|
||||
State int8 `xorm:"-"` //状态:0:running,1:stop
|
||||
GeneralArray []int `json:"-" xorm:"-"`
|
||||
SoldierArray []int `json:"-" xorm:"-"`
|
||||
ConscriptTimeArray []int64 `json:"-" xorm:"-"`
|
||||
ConscriptCntArray []int `json:"-" xorm:"-"`
|
||||
Gens []*General `json:"-" xorm:"-"`
|
||||
CellX int `json:"-" xorm:"-"`
|
||||
CellY int `json:"-" xorm:"-"`
|
||||
}
|
||||
|
||||
func (this *Army) TableName() string {
|
||||
return "tb_army" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
// 是否能出战
|
||||
func (this *Army) IsCanOutWar() bool {
|
||||
return this.Gens[0] != nil && this.Cmd == ArmyCmdIdle
|
||||
}
|
||||
|
||||
func (this *Army) AfterSet(name string, cell xorm.Cell) {
|
||||
if name == "generals" {
|
||||
this.GeneralArray = []int{0, 0, 0}
|
||||
if cell != nil {
|
||||
gs, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(gs, &this.GeneralArray)
|
||||
slog.Debug("army generals loaded", "array", this.GeneralArray)
|
||||
}
|
||||
}
|
||||
} else if name == "soldiers" {
|
||||
this.SoldierArray = []int{0, 0, 0}
|
||||
if cell != nil {
|
||||
ss, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(ss, &this.SoldierArray)
|
||||
slog.Debug("army soldiers loaded", "array", this.SoldierArray)
|
||||
}
|
||||
}
|
||||
} else if name == "conscript_times" {
|
||||
this.ConscriptTimeArray = []int64{0, 0, 0}
|
||||
if cell != nil {
|
||||
ss, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(ss, &this.ConscriptTimeArray)
|
||||
slog.Debug("army conscript times loaded", "array", this.ConscriptTimeArray)
|
||||
}
|
||||
}
|
||||
} else if name == "conscript_cnts" {
|
||||
this.ConscriptCntArray = []int{0, 0, 0}
|
||||
if cell != nil {
|
||||
ss, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(ss, &this.ConscriptCntArray)
|
||||
slog.Debug("army conscript counts loaded", "array", this.ConscriptCntArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Army) beforeModify() {
|
||||
data, _ := json.Marshal(this.GeneralArray)
|
||||
this.Generals = string(data)
|
||||
|
||||
data, _ = json.Marshal(this.SoldierArray)
|
||||
this.Soldiers = string(data)
|
||||
|
||||
data, _ = json.Marshal(this.ConscriptTimeArray)
|
||||
this.ConscriptTimes = string(data)
|
||||
|
||||
data, _ = json.Marshal(this.ConscriptCntArray)
|
||||
this.ConscriptCnts = string(data)
|
||||
}
|
||||
|
||||
func (this *Army) BeforeInsert() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
func (this *Army) BeforeUpdate() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
func (this *Army) ToSoldier() {
|
||||
if this.SoldierArray != nil {
|
||||
data, _ := json.Marshal(this.SoldierArray)
|
||||
this.Soldiers = string(data)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Army) ToGeneral() {
|
||||
if this.GeneralArray != nil {
|
||||
data, _ := json.Marshal(this.GeneralArray)
|
||||
this.Generals = string(data)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取军队阵营
|
||||
func (this *Army) GetCamp() int8 {
|
||||
var camp int8 = 0
|
||||
for _, g := range this.Gens {
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
if camp == 0 {
|
||||
camp = g.GetCamp()
|
||||
} else {
|
||||
if camp != g.GetCamp() {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return camp
|
||||
}
|
||||
|
||||
// 检测征兵是否完成,服务器不做定时任务,用到的时候再检测
|
||||
func (this *Army) CheckConscript() {
|
||||
if this.Cmd == ArmyCmdConscript {
|
||||
curTime := time.Now().Unix()
|
||||
finish := true
|
||||
for i, endTime := range this.ConscriptTimeArray {
|
||||
if endTime > 0 {
|
||||
if endTime <= curTime {
|
||||
this.SoldierArray[i] += this.ConscriptCntArray[i]
|
||||
this.ConscriptCntArray[i] = 0
|
||||
this.ConscriptTimeArray[i] = 0
|
||||
} else {
|
||||
finish = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if finish {
|
||||
this.Cmd = ArmyCmdIdle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 队伍指定的位置是否能变化(上下阵)
|
||||
func (this *Army) PositionCanModify(position int) bool {
|
||||
if position >= 3 || position < 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if this.Cmd == ArmyCmdIdle {
|
||||
return true
|
||||
} else if this.Cmd == ArmyCmdConscript {
|
||||
endTime := this.ConscriptTimeArray[position]
|
||||
return endTime == 0
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Army) ClearConscript() {
|
||||
if this.Cmd == ArmyCmdConscript {
|
||||
for i, _ := range this.ConscriptTimeArray {
|
||||
this.ConscriptCntArray[i] = 0
|
||||
this.ConscriptTimeArray[i] = 0
|
||||
}
|
||||
this.Cmd = ArmyCmdIdle
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Army) IsIdle() bool {
|
||||
return this.Cmd == ArmyCmdIdle
|
||||
}
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *Army) IsCellView() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *Army) IsCanView(rid, x, y int) bool {
|
||||
if ArmyIsInView != nil {
|
||||
return ArmyIsInView(rid, x, y)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *Army) BelongToRId() []int {
|
||||
return []int{this.RId}
|
||||
}
|
||||
|
||||
func (this *Army) PushMsgName() string {
|
||||
return "army.push"
|
||||
}
|
||||
|
||||
func (this *Army) Position() (int, int) {
|
||||
diffTime := this.End.Unix() - this.Start.Unix()
|
||||
passTime := time.Now().Unix() - this.Start.Unix()
|
||||
rate := float32(passTime) / float32(diffTime)
|
||||
x := 0
|
||||
y := 0
|
||||
if this.Cmd == ArmyCmdBack {
|
||||
diffX := this.FromX - this.ToX
|
||||
diffY := this.FromY - this.ToY
|
||||
x = int(rate*float32(diffX)) + this.ToX
|
||||
y = int(rate*float32(diffY)) + this.ToY
|
||||
} else {
|
||||
diffX := this.ToX - this.FromX
|
||||
diffY := this.ToY - this.FromY
|
||||
x = int(rate*float32(diffX)) + this.FromX
|
||||
y = int(rate*float32(diffY)) + this.FromY
|
||||
}
|
||||
|
||||
x = util.MinInt(util.MaxInt(x, 0), global.MapWith)
|
||||
y = util.MinInt(util.MaxInt(y, 0), global.MapHeight)
|
||||
slog.Info("army Position:", "x", x, "y", y)
|
||||
return x, y
|
||||
}
|
||||
|
||||
func (this *Army) TPosition() (int, int) {
|
||||
return this.ToX, this.ToY
|
||||
}
|
||||
|
||||
func (this *Army) ToProto() interface{} {
|
||||
|
||||
p := proto.Army{}
|
||||
p.CityId = this.CityId
|
||||
p.Id = this.Id
|
||||
p.UnionId = GetUnionId(this.RId)
|
||||
p.Order = this.Order
|
||||
p.Generals = this.GeneralArray
|
||||
p.Soldiers = this.SoldierArray
|
||||
p.ConTimes = this.ConscriptTimeArray
|
||||
p.ConCnts = this.ConscriptCntArray
|
||||
p.Cmd = this.Cmd
|
||||
p.State = this.State
|
||||
p.FromX = this.FromX
|
||||
p.FromY = this.FromY
|
||||
p.ToX = this.ToX
|
||||
p.ToY = this.ToY
|
||||
p.Start = this.Start.Unix()
|
||||
p.End = this.End.Unix()
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *Army) Push() {
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *Army) SyncExecute() {
|
||||
dbArmyMgr.push(this)
|
||||
this.Push()
|
||||
this.CellX, this.CellY = this.Position()
|
||||
}
|
||||
|
||||
func (this *Army) CheckSyncCell() {
|
||||
x, y := this.Position()
|
||||
if x != this.CellX || y != this.CellY {
|
||||
this.SyncExecute()
|
||||
}
|
||||
}
|
||||
90
server/slgserver/model/city_facility.go
Normal file
90
server/slgserver/model/city_facility.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbCFMgr *cfDBMgr
|
||||
func init() {
|
||||
dbCFMgr = &cfDBMgr{cs: make(chan *CityFacility, 100)}
|
||||
go dbCFMgr.running()
|
||||
}
|
||||
|
||||
type cfDBMgr struct {
|
||||
cs chan *CityFacility
|
||||
}
|
||||
|
||||
func (this*cfDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case c := <- this.cs:
|
||||
if c.Id >0 {
|
||||
_, err := db.MasterDB.Table(c).ID(c.Id).Cols("facilities").Update(c)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
}else{
|
||||
slog.Warn("update CityFacility fail, because id <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*cfDBMgr) push(c *CityFacility) {
|
||||
this.cs <- c
|
||||
}
|
||||
/*******db 操作end********/
|
||||
|
||||
|
||||
type Facility struct {
|
||||
Name string `json:"name"`
|
||||
PrivateLevel int8 `json:"level"` //等级,外部读的时候不能直接读,要用GetLevel
|
||||
Type int8 `json:"type"`
|
||||
UpTime int64 `json:"up_time"` //升级的时间戳,0表示该等级已经升级完成了
|
||||
}
|
||||
|
||||
//升级这里做成被动触发产生,不做定时
|
||||
func (this* Facility) GetLevel() int8 {
|
||||
if this.UpTime > 0{
|
||||
cur := time.Now().Unix()
|
||||
cost := facility.FConf.CostTime(this.Type, this.PrivateLevel+1)
|
||||
if cur >= this.UpTime + int64(cost){
|
||||
this.PrivateLevel +=1
|
||||
this.UpTime = 0
|
||||
}
|
||||
}
|
||||
return this.PrivateLevel
|
||||
}
|
||||
|
||||
func (this* Facility) CanLV() bool {
|
||||
this.GetLevel()
|
||||
return this.UpTime == 0
|
||||
}
|
||||
|
||||
type CityFacility struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
CityId int `xorm:"cityId"`
|
||||
Facilities string `xorm:"facilities"`
|
||||
}
|
||||
|
||||
func (this *CityFacility) TableName() string {
|
||||
return "tb_city_facility" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
|
||||
func (this *CityFacility) SyncExecute() {
|
||||
dbCFMgr.push(this)
|
||||
}
|
||||
|
||||
func (this*CityFacility) Facility()[]Facility {
|
||||
facilities := make([]Facility, 0)
|
||||
json.Unmarshal([]byte(this.Facilities), &facilities)
|
||||
return facilities
|
||||
}
|
||||
323
server/slgserver/model/coalition.go
Normal file
323
server/slgserver/model/coalition.go
Normal file
@@ -0,0 +1,323 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"time"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
const (
|
||||
UnionDismiss = 0 //解散
|
||||
UnionRunning = 1 //运行中
|
||||
)
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbCoalitionMgr *coalitionDBMgr
|
||||
|
||||
func init() {
|
||||
dbCoalitionMgr = &coalitionDBMgr{coalitions: make(chan *Coalition, 100)}
|
||||
go dbCoalitionMgr.running()
|
||||
}
|
||||
|
||||
type coalitionDBMgr struct {
|
||||
coalitions chan *Coalition
|
||||
}
|
||||
|
||||
func (this *coalitionDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case coalition := <-this.coalitions:
|
||||
if coalition.Id > 0 {
|
||||
_, err := db.MasterDB.Table(coalition).ID(coalition.Id).Cols("name",
|
||||
"members", "chairman", "vice_chairman", "notice", "state").Update(coalition)
|
||||
if err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
} else {
|
||||
slog.Warn("update coalition fail, because id <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *coalitionDBMgr) push(coalition *Coalition) {
|
||||
this.coalitions <- coalition
|
||||
}
|
||||
|
||||
/*******db 操作end********/
|
||||
|
||||
type Coalition struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
Name string `xorm:"name"`
|
||||
Members string `xorm:"members"`
|
||||
MemberArray []int `xorm:"-"`
|
||||
CreateId int `xorm:"create_id"`
|
||||
Chairman int `xorm:"chairman"`
|
||||
ViceChairman int `xorm:"vice_chairman"`
|
||||
Notice string `xorm:"notice"`
|
||||
State int8 `xorm:"state"`
|
||||
Ctime time.Time `xorm:"ctime"`
|
||||
}
|
||||
|
||||
func (this *Coalition) ToProto() interface{} {
|
||||
p := proto.Union{}
|
||||
|
||||
p.Id = this.Id
|
||||
p.Name = this.Name
|
||||
p.Notice = this.Notice
|
||||
p.Cnt = this.Cnt()
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *Coalition) TableName() string {
|
||||
return "tb_coalition" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
func (this *Coalition) AfterSet(name string, cell xorm.Cell) {
|
||||
if name == "members" {
|
||||
if cell != nil {
|
||||
ss, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(ss, &this.MemberArray)
|
||||
}
|
||||
if this.MemberArray == nil {
|
||||
this.MemberArray = []int{}
|
||||
slog.Debug("coalition members loaded", "members", this.MemberArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Coalition) BeforeInsert() {
|
||||
data, _ := json.Marshal(this.MemberArray)
|
||||
this.Members = string(data)
|
||||
}
|
||||
|
||||
func (this *Coalition) BeforeUpdate() {
|
||||
data, _ := json.Marshal(this.MemberArray)
|
||||
this.Members = string(data)
|
||||
}
|
||||
|
||||
func (this *Coalition) Cnt() int {
|
||||
return len(this.MemberArray)
|
||||
}
|
||||
|
||||
func (this *Coalition) SyncExecute() {
|
||||
dbCoalitionMgr.push(this)
|
||||
}
|
||||
|
||||
type CoalitionApply struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
UnionId int `xorm:"union_id"`
|
||||
RId int `xorm:"rid"`
|
||||
State int8 `xorm:"state"`
|
||||
Ctime time.Time `xorm:"ctime"`
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) TableName() string {
|
||||
return "tb_coalition_apply" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *CoalitionApply) IsCellView() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) IsCanView(rid, x, y int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) BelongToRId() []int {
|
||||
r := GetMainMembers(this.UnionId)
|
||||
return append(r, this.RId)
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) PushMsgName() string {
|
||||
return "unionApply.push"
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) Position() (int, int) {
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) TPosition() (int, int) {
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) ToProto() interface{} {
|
||||
p := proto.ApplyItem{}
|
||||
p.RId = this.RId
|
||||
p.Id = this.Id
|
||||
p.NickName = GetRoleNickName(this.RId)
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *CoalitionApply) Push() {
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *CoalitionApply) SyncExecute() {
|
||||
this.Push()
|
||||
}
|
||||
|
||||
const (
|
||||
UnionOpCreate = 0 //创建
|
||||
UnionOpDismiss = 1 //解散
|
||||
UnionOpJoin = 2 //加入
|
||||
UnionOpExit = 3 //退出
|
||||
UnionOpKick = 4 //踢出
|
||||
UnionOpAppoint = 5 //任命
|
||||
UnionOpAbdicate = 6 //禅让
|
||||
UnionOpModNotice = 7 //修改公告
|
||||
)
|
||||
|
||||
type CoalitionLog struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
UnionId int `xorm:"union_id"`
|
||||
OPRId int `xorm:"op_rid"`
|
||||
TargetId int `xorm:"target_id"`
|
||||
State int8 `xorm:"state"`
|
||||
Des string `xorm:"des"`
|
||||
Ctime time.Time `xorm:"ctime"`
|
||||
}
|
||||
|
||||
func (this *CoalitionLog) TableName() string {
|
||||
return "tb_coalition_log" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
func (this *CoalitionLog) ToProto() interface{} {
|
||||
p := proto.UnionLog{}
|
||||
p.OPRId = this.OPRId
|
||||
p.TargetId = this.TargetId
|
||||
p.Des = this.Des
|
||||
p.State = this.State
|
||||
p.Ctime = this.Ctime.UnixNano() / 1e6
|
||||
return p
|
||||
}
|
||||
|
||||
func NewCreate(opNickName string, unionId int, opRId int) {
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: 0,
|
||||
State: UnionOpCreate,
|
||||
Des: opNickName + " 创建了联盟",
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
|
||||
func NewDismiss(opNickName string, unionId int, opRId int) {
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: 0,
|
||||
State: UnionOpDismiss,
|
||||
Des: opNickName + " 解散了联盟",
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
|
||||
func NewJoin(targetNickName string, unionId int, opRId int, targetId int) {
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: targetId,
|
||||
State: UnionOpJoin,
|
||||
Des: targetNickName + " 加入了联盟",
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
|
||||
func NewExit(opNickName string, unionId int, opRId int) {
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: opRId,
|
||||
State: UnionOpExit,
|
||||
Des: opNickName + " 退出了联盟",
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
|
||||
func NewKick(opNickName string, targetNickName string, unionId int, opRId int, targetId int) {
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: targetId,
|
||||
State: UnionOpKick,
|
||||
Des: opNickName + " 将 " + targetNickName + " 踢出了联盟",
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
|
||||
func NewAppoint(opNickName string, targetNickName string,
|
||||
unionId int, opRId int, targetId int, memberType int) {
|
||||
|
||||
title := ""
|
||||
if memberType == proto.UnionChairman {
|
||||
title = "盟主"
|
||||
} else if memberType == proto.UnionViceChairman {
|
||||
title = "副盟主"
|
||||
} else {
|
||||
title = "普通成员"
|
||||
}
|
||||
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: targetId,
|
||||
State: UnionOpAppoint,
|
||||
Des: opNickName + " 将 " + targetNickName + " 任命为 " + title,
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
|
||||
func NewAbdicate(opNickName string, targetNickName string,
|
||||
unionId int, opRId int, targetId int, memberType int) {
|
||||
|
||||
title := ""
|
||||
if memberType == proto.UnionChairman {
|
||||
title = "盟主"
|
||||
} else if memberType == proto.UnionViceChairman {
|
||||
title = "副盟主"
|
||||
} else {
|
||||
title = "普通成员"
|
||||
}
|
||||
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: targetId,
|
||||
State: UnionOpAbdicate,
|
||||
Des: opNickName + " 将 " + title + " 禅让给 " + targetNickName,
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
|
||||
func NewModNotice(opNickName string, unionId int, opRId int) {
|
||||
ulog := &CoalitionLog{
|
||||
UnionId: unionId,
|
||||
OPRId: opRId,
|
||||
TargetId: 0,
|
||||
State: UnionOpModNotice,
|
||||
Des: opNickName + " 修改了公告",
|
||||
Ctime: time.Now(),
|
||||
}
|
||||
db.MasterDB.InsertOne(ulog)
|
||||
}
|
||||
326
server/slgserver/model/general.go
Normal file
326
server/slgserver/model/general.go
Normal file
@@ -0,0 +1,326 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/general"
|
||||
"time"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
const (
|
||||
GeneralNormal = 0 //正常
|
||||
GeneralComposeStar = 1 //星级合成
|
||||
GeneralConvert = 2 //转换
|
||||
)
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbGeneralMgr *generalDBMgr
|
||||
|
||||
func init() {
|
||||
dbGeneralMgr = &generalDBMgr{gs: make(chan *General, 100)}
|
||||
go dbGeneralMgr.running()
|
||||
}
|
||||
|
||||
type generalDBMgr struct {
|
||||
gs chan *General
|
||||
}
|
||||
|
||||
func (this *generalDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case g := <-this.gs:
|
||||
if g.Id > 0 && g.RId > 0 {
|
||||
_, err := db.MasterDB.Table(g).ID(g.Id).Cols(
|
||||
"level", "exp", "order", "cityId",
|
||||
"physical_power", "star_lv", "has_pr_point",
|
||||
"use_pr_point", "force_added", "strategy_added",
|
||||
"defense_added", "speed_added", "destroy_added",
|
||||
"parentId", "compose_type", "skills", "state").Update(g)
|
||||
if err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
} else {
|
||||
slog.Warn("update general fail, because id <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *generalDBMgr) push(g *General) {
|
||||
this.gs <- g
|
||||
}
|
||||
|
||||
/*******db 操作end********/
|
||||
|
||||
const SkillLimit = 3
|
||||
|
||||
func NewGeneral(cfgId int, rid int, level int8) (*General, bool) {
|
||||
|
||||
cfg, ok := general.General.GMap[cfgId]
|
||||
if ok {
|
||||
sa := make([]*proto.GSkill, SkillLimit)
|
||||
ss, _ := json.Marshal(sa)
|
||||
g := &General{
|
||||
PhysicalPower: static_conf.Basic.General.PhysicalPowerLimit,
|
||||
RId: rid,
|
||||
CfgId: cfg.CfgId,
|
||||
Order: 0,
|
||||
CityId: 0,
|
||||
Level: level,
|
||||
CreatedAt: time.Now(),
|
||||
CurArms: cfg.Arms[0],
|
||||
HasPrPoint: 0,
|
||||
UsePrPoint: 0,
|
||||
AttackDis: 0,
|
||||
ForceAdded: 0,
|
||||
StrategyAdded: 0,
|
||||
DefenseAdded: 0,
|
||||
SpeedAdded: 0,
|
||||
DestroyAdded: 0,
|
||||
Star: cfg.Star,
|
||||
StarLv: 0,
|
||||
ParentId: 0,
|
||||
SkillsArray: sa,
|
||||
Skills: string(ss),
|
||||
State: GeneralNormal,
|
||||
}
|
||||
|
||||
if _, err := db.MasterDB.Table(General{}).Insert(g); err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
return nil, false
|
||||
} else {
|
||||
return g, true
|
||||
}
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
type General struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
CfgId int `xorm:"cfgId"`
|
||||
PhysicalPower int `xorm:"physical_power"`
|
||||
Level int8 `xorm:"level"`
|
||||
Exp int `xorm:"exp"`
|
||||
Order int8 `xorm:"order"`
|
||||
CityId int `xorm:"cityId"`
|
||||
CreatedAt time.Time `xorm:"created_at"`
|
||||
CurArms int `xorm:"arms"`
|
||||
HasPrPoint int `xorm:"has_pr_point"`
|
||||
UsePrPoint int `xorm:"use_pr_point"`
|
||||
AttackDis int `xorm:"attack_distance"`
|
||||
ForceAdded int `xorm:"force_added"`
|
||||
StrategyAdded int `xorm:"strategy_added"`
|
||||
DefenseAdded int `xorm:"defense_added"`
|
||||
SpeedAdded int `xorm:"speed_added"`
|
||||
DestroyAdded int `xorm:"destroy_added"`
|
||||
StarLv int8 `xorm:"star_lv"`
|
||||
Star int8 `xorm:"star"`
|
||||
ParentId int `xorm:"parentId"`
|
||||
Skills string `xorm:"skills"`
|
||||
SkillsArray []*proto.GSkill `xorm:"-"`
|
||||
State int8 `xorm:"state"`
|
||||
}
|
||||
|
||||
func (this *General) TableName() string {
|
||||
return "tb_general" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
func (this *General) AfterSet(name string, cell xorm.Cell) {
|
||||
if name == "skills" {
|
||||
this.SkillsArray = make([]*proto.GSkill, 3)
|
||||
if cell != nil {
|
||||
gs, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(gs, &this.Skills)
|
||||
slog.Debug("general skills loaded", "skills", this.SkillsArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *General) beforeModify() {
|
||||
data, _ := json.Marshal(this.SkillsArray)
|
||||
this.Skills = string(data)
|
||||
}
|
||||
|
||||
func (this *General) BeforeInsert() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
func (this *General) BeforeUpdate() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
func (this *General) GetDestroy() int {
|
||||
cfg, ok := general.General.GMap[this.CfgId]
|
||||
if ok {
|
||||
return cfg.Destroy + cfg.DestroyGrow*int(this.Level) + this.DestroyAdded
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *General) IsActive() bool {
|
||||
return this.State == GeneralNormal
|
||||
}
|
||||
|
||||
func (this *General) GetSpeed() int {
|
||||
cfg, ok := general.General.GMap[this.CfgId]
|
||||
if ok {
|
||||
return cfg.Speed + cfg.SpeedGrow*int(this.Level) + this.SpeedAdded
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *General) GetForce() int {
|
||||
cfg, ok := general.General.GMap[this.CfgId]
|
||||
if ok {
|
||||
return cfg.Force + cfg.ForceGrow*int(this.Level) + this.ForceAdded
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *General) GetDefense() int {
|
||||
cfg, ok := general.General.GMap[this.CfgId]
|
||||
if ok {
|
||||
return cfg.Defense + cfg.DefenseGrow*int(this.Level) + this.DefenseAdded
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *General) GetStrategy() int {
|
||||
cfg, ok := general.General.GMap[this.CfgId]
|
||||
if ok {
|
||||
return cfg.Strategy + cfg.StrategyGrow*int(this.Level) + this.StrategyAdded
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 获取阵营
|
||||
func (this *General) GetCamp() int8 {
|
||||
cfg, ok := general.General.GMap[this.CfgId]
|
||||
if ok {
|
||||
return cfg.Camp
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *General) UpSkill(skillId int, cfgId int, pos int) bool {
|
||||
if pos < 0 || pos >= SkillLimit {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, skill := range this.SkillsArray {
|
||||
if skill != nil && skill.Id == skillId {
|
||||
//已经上过同类型的技能了
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
s := this.SkillsArray[pos]
|
||||
if s == nil {
|
||||
this.SkillsArray[pos] = &proto.GSkill{Id: skillId, Lv: 1, CfgId: cfgId}
|
||||
return true
|
||||
} else {
|
||||
if s.Id == 0 {
|
||||
s.Id = skillId
|
||||
s.CfgId = cfgId
|
||||
s.Lv = 1
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *General) DownSkill(skillId int, pos int) bool {
|
||||
if pos < 0 || pos >= SkillLimit {
|
||||
return false
|
||||
}
|
||||
s := this.SkillsArray[pos]
|
||||
if s != nil && s.Id == skillId {
|
||||
s.Id = 0
|
||||
s.Lv = 0
|
||||
s.CfgId = 0
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *General) PosSkill(pos int) (*proto.GSkill, error) {
|
||||
if pos >= len(this.SkillsArray) {
|
||||
return nil, errors.New("skill index out of range")
|
||||
}
|
||||
return this.SkillsArray[pos], nil
|
||||
}
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *General) IsCellView() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *General) IsCanView(rid, x, y int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *General) BelongToRId() []int {
|
||||
return []int{this.RId}
|
||||
}
|
||||
|
||||
func (this *General) PushMsgName() string {
|
||||
return "general.push"
|
||||
}
|
||||
|
||||
func (this *General) Position() (int, int) {
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *General) TPosition() (int, int) {
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *General) ToProto() interface{} {
|
||||
p := proto.General{}
|
||||
p.CityId = this.CityId
|
||||
p.Order = this.Order
|
||||
p.PhysicalPower = this.PhysicalPower
|
||||
p.Id = this.Id
|
||||
p.CfgId = this.CfgId
|
||||
p.Level = this.Level
|
||||
p.Exp = this.Exp
|
||||
p.CurArms = this.CurArms
|
||||
p.HasPrPoint = this.HasPrPoint
|
||||
p.UsePrPoint = this.UsePrPoint
|
||||
p.AttackDis = this.AttackDis
|
||||
p.ForceAdded = this.ForceAdded
|
||||
p.StrategyAdded = this.StrategyAdded
|
||||
p.DefenseAdded = this.DefenseAdded
|
||||
p.SpeedAdded = this.SpeedAdded
|
||||
p.DestroyAdded = this.DestroyAdded
|
||||
p.StarLv = this.StarLv
|
||||
p.Star = this.Star
|
||||
p.State = this.State
|
||||
p.ParentId = this.ParentId
|
||||
p.Skills = this.SkillsArray
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *General) Push() {
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *General) SyncExecute() {
|
||||
dbGeneralMgr.push(this)
|
||||
this.Push()
|
||||
}
|
||||
285
server/slgserver/model/map_role_build.go
Normal file
285
server/slgserver/model/map_role_build.go
Normal file
@@ -0,0 +1,285 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
MapBuildSysFortress = 50 //系统要塞
|
||||
MapBuildSysCity = 51 //系统城市
|
||||
MapBuildFortress = 56 //玩家要塞
|
||||
)
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbRBMgr *rbDBMgr
|
||||
func init() {
|
||||
dbRBMgr = &rbDBMgr{builds: make(chan *MapRoleBuild, 100)}
|
||||
go dbRBMgr.running()
|
||||
}
|
||||
|
||||
type rbDBMgr struct {
|
||||
builds chan *MapRoleBuild
|
||||
}
|
||||
|
||||
func (this *rbDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case b := <- this.builds:
|
||||
if b.Id >0 {
|
||||
_, err := db.MasterDB.Table(b).ID(b.Id).Cols(
|
||||
"rid", "name", "type", "level", "op_level",
|
||||
"cur_durable", "max_durable", "occupy_time",
|
||||
"giveUp_time", "end_time").Update(b)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
}else{
|
||||
slog.Warn("update role build fail, because id <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *rbDBMgr) push(b *MapRoleBuild) {
|
||||
this.builds <- b
|
||||
}
|
||||
/*******db 操作end********/
|
||||
|
||||
type MapRoleBuild struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
Type int8 `xorm:"type"`
|
||||
Level int8 `xorm:"level"`
|
||||
OPLevel int8 `xorm:"op_level"` //操作level
|
||||
X int `xorm:"x"`
|
||||
Y int `xorm:"y"`
|
||||
Name string `xorm:"name"`
|
||||
Wood int `xorm:"-"`
|
||||
Iron int `xorm:"-"`
|
||||
Stone int `xorm:"-"`
|
||||
Grain int `xorm:"-"`
|
||||
Defender int `xorm:"-"`
|
||||
CurDurable int `xorm:"cur_durable"`
|
||||
MaxDurable int `xorm:"max_durable"`
|
||||
OccupyTime time.Time `xorm:"occupy_time"`
|
||||
EndTime time.Time `xorm:"end_time"` //建造或升级完的时间
|
||||
GiveUpTime int64 `xorm:"giveUp_time"`
|
||||
}
|
||||
|
||||
func (this *MapRoleBuild) TableName() string {
|
||||
return "tb_map_role_build" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) Init() {
|
||||
if cfg, _ := static_conf.MapBuildConf.BuildConfig(this.Type, this.Level); cfg != nil {
|
||||
this.Name = cfg.Name
|
||||
this.Level = cfg.Level
|
||||
this.Type = cfg.Type
|
||||
this.Wood = cfg.Wood
|
||||
this.Iron = cfg.Iron
|
||||
this.Stone = cfg.Stone
|
||||
this.Grain = cfg.Grain
|
||||
this.MaxDurable = cfg.Durable
|
||||
this.CurDurable = cfg.Durable
|
||||
this.Defender = cfg.Defender
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (this* MapRoleBuild) Reset() {
|
||||
ok, t, level := MapResTypeLevel(this.X, this.Y)
|
||||
if ok {
|
||||
if cfg, _ := static_conf.MapBuildConf.BuildConfig(t, level); cfg != nil {
|
||||
this.Name = cfg.Name
|
||||
this.Level = cfg.Level
|
||||
this.Type = cfg.Type
|
||||
this.Wood = cfg.Wood
|
||||
this.Iron = cfg.Iron
|
||||
this.Stone = cfg.Stone
|
||||
this.Grain = cfg.Grain
|
||||
this.MaxDurable = cfg.Durable
|
||||
this.Defender = cfg.Defender
|
||||
}
|
||||
}
|
||||
|
||||
this.GiveUpTime = 0
|
||||
this.RId = 0
|
||||
this.EndTime = time.Time{}
|
||||
this.OPLevel = this.Level
|
||||
this.CurDurable = util.MinInt(this.MaxDurable, this.CurDurable)
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) ConvertToRes() {
|
||||
rid := this.RId
|
||||
giveUp := this.GiveUpTime
|
||||
this.Reset()
|
||||
this.RId = rid
|
||||
this.GiveUpTime = giveUp
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) IsInGiveUp() bool {
|
||||
return this.GiveUpTime != 0
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) IsWarFree() bool {
|
||||
curTime := time.Now().Unix()
|
||||
if curTime - this.OccupyTime.Unix() < static_conf.Basic.Build.WarFree{
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) IsResBuild() bool {
|
||||
return this.Grain > 0 || this.Stone > 0 || this.Iron > 0 || this.Wood > 0
|
||||
}
|
||||
|
||||
//是否有修改等级权限
|
||||
func (this* MapRoleBuild) IsHaveModifyLVAuth() bool {
|
||||
return this.Type == MapBuildFortress
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) IsBusy() bool{
|
||||
if this.Level != this.OPLevel{
|
||||
return true
|
||||
}else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) IsRoleFortress() bool {
|
||||
return this.Type == MapBuildFortress
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) IsSysFortress() bool {
|
||||
return this.Type == MapBuildSysFortress
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) IsSysCity() bool {
|
||||
return this.Type == MapBuildSysCity
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) CellRadius() int {
|
||||
if this.IsSysCity(){
|
||||
if this.Level >= 8{
|
||||
return 3
|
||||
}else if this.Level >= 5{
|
||||
return 2
|
||||
}else {
|
||||
return 1
|
||||
}
|
||||
}else{
|
||||
return 0
|
||||
}
|
||||
}
|
||||
//是否有调兵权限
|
||||
func (this* MapRoleBuild) IsHasTransferAuth() bool {
|
||||
return this.Type == MapBuildFortress || this.Type == MapBuildSysFortress
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) BuildOrUp(cfg static_conf.BCLevelCfg) {
|
||||
this.Type = cfg.Type
|
||||
this.Level = cfg.Level -1
|
||||
this.Name = cfg.Name
|
||||
this.OPLevel = cfg.Level
|
||||
this.GiveUpTime = 0
|
||||
|
||||
this.Wood = 0
|
||||
this.Iron = 0
|
||||
this.Stone = 0
|
||||
this.Grain = 0
|
||||
this.EndTime = time.Now().Add(time.Duration(cfg.Time) * time.Second)
|
||||
}
|
||||
|
||||
func (this* MapRoleBuild) DelBuild(cfg static_conf.BCLevelCfg) {
|
||||
this.OPLevel = 0
|
||||
this.EndTime = time.Now().Add(time.Duration(cfg.Time) * time.Second)
|
||||
}
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *MapRoleBuild) IsCellView() bool{
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *MapRoleBuild) IsCanView(rid, x, y int) bool{
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func (this *MapRoleBuild) BelongToRId() []int{
|
||||
return []int{this.RId}
|
||||
}
|
||||
|
||||
func (this *MapRoleBuild) PushMsgName() string{
|
||||
return "roleBuild.push"
|
||||
}
|
||||
|
||||
func (this *MapRoleBuild) Position() (int, int){
|
||||
return this.X, this.Y
|
||||
}
|
||||
|
||||
func (this *MapRoleBuild) TPosition() (int, int){
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *MapRoleBuild) ToProto() interface{}{
|
||||
|
||||
p := proto.MapRoleBuild{}
|
||||
p.RNick = GetRoleNickName(this.RId)
|
||||
p.UnionId = GetUnionId(this.RId)
|
||||
p.UnionName = GetUnionName(p.UnionId)
|
||||
p.ParentId = GetParentId(this.RId)
|
||||
p.X = this.X
|
||||
p.Y = this.Y
|
||||
p.Type = this.Type
|
||||
p.RId = this.RId
|
||||
p.Name = this.Name
|
||||
|
||||
p.OccupyTime = this.OccupyTime.UnixNano()/1e6
|
||||
p.GiveUpTime = this.GiveUpTime*1000
|
||||
p.EndTime = this.EndTime.UnixNano()/1e6
|
||||
|
||||
if this.EndTime.IsZero() == false{
|
||||
if this.IsHasTransferAuth(){
|
||||
if time.Now().Before(this.EndTime) == false{
|
||||
|
||||
if this.OPLevel == 0{
|
||||
this.ConvertToRes()
|
||||
}else{
|
||||
this.Level = this.OPLevel
|
||||
this.EndTime = time.Time{}
|
||||
cfg, ok := static_conf.MapBCConf.BuildConfig(this.Type, this.Level)
|
||||
if ok {
|
||||
this.MaxDurable = cfg.Durable
|
||||
this.CurDurable = util.MinInt(this.MaxDurable, this.CurDurable)
|
||||
this.Defender = cfg.Defender
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.CurDurable = this.CurDurable
|
||||
p.MaxDurable = this.MaxDurable
|
||||
p.Defender = this.Defender
|
||||
p.Level = this.Level
|
||||
p.OPLevel = this.OPLevel
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *MapRoleBuild) Push(){
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *MapRoleBuild) SyncExecute() {
|
||||
dbRBMgr.push(this)
|
||||
this.Push()
|
||||
}
|
||||
144
server/slgserver/model/map_role_city.go
Normal file
144
server/slgserver/model/map_role_city.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbRCMgr *rcDBMgr
|
||||
func init() {
|
||||
dbRCMgr = &rcDBMgr{builds: make(chan *MapRoleCity, 100)}
|
||||
go dbRCMgr.running()
|
||||
}
|
||||
|
||||
type rcDBMgr struct {
|
||||
builds chan *MapRoleCity
|
||||
}
|
||||
|
||||
func (this*rcDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case b := <- this.builds:
|
||||
if b.CityId >0 {
|
||||
_, err := db.MasterDB.Table(b).ID(b.CityId).Cols("cur_durable", "occupy_time").Update(b)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
}else{
|
||||
slog.Warn("update role city build fail, because CityId <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*rcDBMgr) push(b *MapRoleCity) {
|
||||
this.builds <- b
|
||||
}
|
||||
/*******db 操作end********/
|
||||
|
||||
type MapRoleCity struct {
|
||||
mutex sync.Mutex `xorm:"-"`
|
||||
CityId int `xorm:"cityId pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
Name string `xorm:"name" validate:"min=4,max=20,regexp=^[a-zA-Z0-9_]*$"`
|
||||
X int `xorm:"x"`
|
||||
Y int `xorm:"y"`
|
||||
IsMain int8 `xorm:"is_main"`
|
||||
CurDurable int `xorm:"cur_durable"`
|
||||
CreatedAt time.Time `xorm:"created_at"`
|
||||
OccupyTime time.Time `xorm:"occupy_time"`
|
||||
}
|
||||
|
||||
func (this* MapRoleCity) IsWarFree() bool {
|
||||
curTime := time.Now().Unix()
|
||||
if curTime - this.OccupyTime.Unix() < static_conf.Basic.Build.WarFree{
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this*MapRoleCity) DurableChange(change int) {
|
||||
this.mutex.Lock()
|
||||
defer this.mutex.Unlock()
|
||||
|
||||
t := this.CurDurable + change
|
||||
if t < 0{
|
||||
this.CurDurable = 0
|
||||
}else{
|
||||
this.CurDurable = util.MinInt(GetMaxDurable(this.CityId), t)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) Level() int8 {
|
||||
return GetCityLv(this.CityId)
|
||||
}
|
||||
|
||||
func (this* MapRoleCity) CellRadius() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) TableName() string {
|
||||
return "tb_map_role_city" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *MapRoleCity) IsCellView() bool{
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) IsCanView(rid, x, y int) bool{
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) BelongToRId() []int{
|
||||
return []int{this.RId}
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) PushMsgName() string{
|
||||
return "roleCity.push"
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) Position() (int, int){
|
||||
return this.X, this.Y
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) TPosition() (int, int){
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) ToProto() interface{}{
|
||||
p := proto.MapRoleCity{}
|
||||
p.X = this.X
|
||||
p.Y = this.Y
|
||||
p.CityId = this.CityId
|
||||
p.UnionId = GetUnionId(this.RId)
|
||||
p.UnionName = GetUnionName(p.UnionId)
|
||||
p.ParentId = GetParentId(this.RId)
|
||||
p.MaxDurable = GetMaxDurable(this.RId)
|
||||
p.CurDurable = this.CurDurable
|
||||
p.Level = this.Level()
|
||||
p.RId = this.RId
|
||||
p.Name = this.Name
|
||||
p.IsMain = this.IsMain == 1
|
||||
p.OccupyTime = this.OccupyTime.UnixNano()/1e6
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *MapRoleCity) Push(){
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *MapRoleCity) SyncExecute() {
|
||||
dbRCMgr.push(this)
|
||||
this.Push()
|
||||
}
|
||||
11
server/slgserver/model/national_map.go
Normal file
11
server/slgserver/model/national_map.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
type NationalMap struct {
|
||||
MId int `xorm:"mid"`
|
||||
X int `xorm:"x"`
|
||||
Y int `xorm:"y"`
|
||||
Type int8 `xorm:"type"`
|
||||
Level int8 `xorm:"level"`
|
||||
}
|
||||
|
||||
|
||||
36
server/slgserver/model/role.go
Normal file
36
server/slgserver/model/role.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Role struct {
|
||||
RId int `xorm:"rid pk autoincr"`
|
||||
UId int `xorm:"uid"`
|
||||
NickName string `xorm:"nick_name" validate:"min=4,max=20,regexp=^[a-zA-Z0-9_]*$"`
|
||||
Balance int `xorm:"balance"`
|
||||
HeadId int16 `xorm:"headId"`
|
||||
Sex int8 `xorm:"sex"`
|
||||
Profile string `xorm:"profile"`
|
||||
LoginTime time.Time `xorm:"login_time"`
|
||||
LogoutTime time.Time `xorm:"logout_time"`
|
||||
CreatedAt time.Time `xorm:"created_at"`
|
||||
}
|
||||
|
||||
func (this *Role) TableName() string {
|
||||
return "tb_role" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
func (this *Role) ToProto() interface{}{
|
||||
p := proto.Role{}
|
||||
p.UId = this.UId
|
||||
p.RId = this.RId
|
||||
p.Sex = this.Sex
|
||||
p.NickName = this.NickName
|
||||
p.HeadId = this.HeadId
|
||||
p.Balance = this.Balance
|
||||
p.Profile = this.Profile
|
||||
return p
|
||||
}
|
||||
153
server/slgserver/model/role_attribute.go
Normal file
153
server/slgserver/model/role_attribute.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"time"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbRAttrMgr *roleAttrDBMgr
|
||||
|
||||
func init() {
|
||||
dbRAttrMgr = &roleAttrDBMgr{rattr: make(chan *RoleAttribute, 100)}
|
||||
go dbRAttrMgr.running()
|
||||
}
|
||||
|
||||
type roleAttrDBMgr struct {
|
||||
rattr chan *RoleAttribute
|
||||
}
|
||||
|
||||
func (this *roleAttrDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case attr := <-this.rattr:
|
||||
if attr.Id > 0 {
|
||||
_, err := db.MasterDB.Table(attr).ID(attr.Id).Cols(
|
||||
"parent_id", "collect_times", "last_collect_time", "pos_tags").Update(attr)
|
||||
if err != nil {
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
} else {
|
||||
slog.Warn("update role attr fail, because id <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *roleAttrDBMgr) push(attr *RoleAttribute) {
|
||||
this.rattr <- attr
|
||||
}
|
||||
|
||||
/*******db 操作end********/
|
||||
|
||||
type RoleAttribute struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
UnionId int `xorm:"-"` //联盟id
|
||||
ParentId int `xorm:"parent_id"` //上级id(被沦陷)
|
||||
CollectTimes int8 `xorm:"collect_times"` //征收次数
|
||||
LastCollectTime time.Time `xorm:"last_collect_time"` //最后征收的时间
|
||||
PosTags string `xorm:"pos_tags"` //位置标记
|
||||
PosTagArray []proto.PosTag `xorm:"-"`
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) TableName() string {
|
||||
return "tb_role_attribute" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) AfterSet(name string, cell xorm.Cell) {
|
||||
if name == "pos_tags" {
|
||||
this.PosTagArray = make([]proto.PosTag, 0)
|
||||
if cell != nil {
|
||||
data, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(data, &this.PosTagArray)
|
||||
slog.Debug("role pos tags loaded", "tags", this.PosTagArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) beforeModify() {
|
||||
if this.PosTagArray == nil {
|
||||
this.PosTagArray = make([]proto.PosTag, 0)
|
||||
}
|
||||
data, _ := json.Marshal(this.PosTagArray)
|
||||
this.PosTags = string(data)
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) BeforeInsert() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) BeforeUpdate() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) RemovePosTag(x, y int) {
|
||||
tags := make([]proto.PosTag, 0)
|
||||
for _, tag := range this.PosTagArray {
|
||||
if tag.X != x || tag.Y != y {
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
}
|
||||
this.PosTagArray = tags
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) AddPosTag(x, y int, name string) {
|
||||
ok := true
|
||||
for _, tag := range this.PosTagArray {
|
||||
if tag.X == x && tag.Y == y {
|
||||
ok = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
this.PosTagArray = append(this.PosTagArray, proto.PosTag{X: x, Y: y, Name: name})
|
||||
}
|
||||
}
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *RoleAttribute) IsCellView() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) IsCanView(rid, x, y int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) BelongToRId() []int {
|
||||
return []int{this.RId}
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) PushMsgName() string {
|
||||
return "roleAttr.push"
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) ToProto() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) Position() (int, int) {
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) TPosition() (int, int) {
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *RoleAttribute) Push() {
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *RoleAttribute) SyncExecute() {
|
||||
dbRAttrMgr.push(this)
|
||||
}
|
||||
122
server/slgserver/model/role_res.go
Normal file
122
server/slgserver/model/role_res.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
)
|
||||
|
||||
type Yield struct {
|
||||
Wood int
|
||||
Iron int
|
||||
Stone int
|
||||
Grain int
|
||||
Gold int
|
||||
}
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbRResMgr *roleResDBMgr
|
||||
func init() {
|
||||
dbRResMgr = &roleResDBMgr{ress: make(chan *RoleRes, 100)}
|
||||
go dbRResMgr.running()
|
||||
}
|
||||
|
||||
type roleResDBMgr struct {
|
||||
ress chan *RoleRes
|
||||
}
|
||||
|
||||
func (this *roleResDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case res := <- this.ress:
|
||||
if res.Id >0 {
|
||||
_, err := db.MasterDB.Table(res).ID(res.Id).Cols(
|
||||
"wood", "iron", "stone",
|
||||
"grain", "gold", "decree").Update(res)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
}else{
|
||||
slog.Warn("update role build fail, because id <= 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *roleResDBMgr) push(res *RoleRes) {
|
||||
this.ress <- res
|
||||
}
|
||||
/*******db 操作end********/
|
||||
|
||||
|
||||
type RoleRes struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
Wood int `xorm:"wood"`
|
||||
Iron int `xorm:"iron"`
|
||||
Stone int `xorm:"stone"`
|
||||
Grain int `xorm:"grain"`
|
||||
Gold int `xorm:"gold"`
|
||||
Decree int `xorm:"decree"` //令牌
|
||||
}
|
||||
|
||||
func (this *RoleRes) TableName() string {
|
||||
return "tb_role_res" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *RoleRes) IsCellView() bool{
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *RoleRes) IsCanView(rid, x, y int) bool{
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *RoleRes) BelongToRId() []int{
|
||||
return []int{this.RId}
|
||||
}
|
||||
|
||||
func (this *RoleRes) PushMsgName() string{
|
||||
return "roleRes.push"
|
||||
}
|
||||
|
||||
func (this *RoleRes) ToProto() interface{}{
|
||||
p := proto.RoleRes{}
|
||||
p.Gold = this.Gold
|
||||
p.Grain = this.Grain
|
||||
p.Stone = this.Stone
|
||||
p.Iron = this.Iron
|
||||
p.Wood = this.Wood
|
||||
p.Decree = this.Decree
|
||||
|
||||
y := GetYield(this.RId)
|
||||
p.GoldYield = y.Gold
|
||||
p.GrainYield = y.Grain
|
||||
p.StoneYield = y.Stone
|
||||
p.IronYield = y.Iron
|
||||
p.WoodYield = y.Wood
|
||||
p.DepotCapacity = GetDepotCapacity(this.RId)
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *RoleRes) Position() (int, int){
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *RoleRes) TPosition() (int, int){
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *RoleRes) Push(){
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *RoleRes) SyncExecute() {
|
||||
dbRResMgr.push(this)
|
||||
this.Push()
|
||||
}
|
||||
178
server/slgserver/model/skill.go
Normal file
178
server/slgserver/model/skill.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"slgserver/server/slgserver/static_conf/skill"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
|
||||
/*******db 操作begin********/
|
||||
var dbSkillMgr *skillDBMgr
|
||||
func init() {
|
||||
dbSkillMgr = &skillDBMgr{skills: make(chan *Skill, 100)}
|
||||
go dbSkillMgr.running()
|
||||
}
|
||||
|
||||
|
||||
type skillDBMgr struct {
|
||||
skills chan *Skill
|
||||
}
|
||||
|
||||
func (this*skillDBMgr) running() {
|
||||
for true {
|
||||
select {
|
||||
case skill := <- this.skills:
|
||||
if skill.Id >0 {
|
||||
_, err := db.MasterDB.Table(skill).ID(skill.Id).Cols(
|
||||
"cfgId", "belong_generals", "rid").Update(skill)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
}else{
|
||||
db.MasterDB.Table(skill).InsertOne(skill)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this*skillDBMgr) push(skill *Skill) {
|
||||
this.skills <- skill
|
||||
}
|
||||
/*******db 操作end********/
|
||||
|
||||
//军队
|
||||
type Skill struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
RId int `xorm:"rid"`
|
||||
CfgId int `xorm:"cfgId"`
|
||||
BelongGenerals string `xorm:"belong_generals"`
|
||||
Generals []int `xorm:"-"`
|
||||
}
|
||||
|
||||
func NewSkill(rid int, cfgId int) *Skill{
|
||||
return &Skill{
|
||||
CfgId: cfgId,
|
||||
RId: rid,
|
||||
Generals: []int{},
|
||||
BelongGenerals: "[]",
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Skill) TableName() string {
|
||||
return "tb_skill" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
|
||||
func (this *Skill) AfterSet(name string, cell xorm.Cell){
|
||||
if name == "belong_generals"{
|
||||
this.Generals = []int{}
|
||||
if cell != nil{
|
||||
gs, ok := (*cell).([]uint8)
|
||||
if ok {
|
||||
json.Unmarshal(gs, &this.BelongGenerals)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Skill) beforeModify() {
|
||||
data, _ := json.Marshal(this.Generals)
|
||||
this.BelongGenerals = string(data)
|
||||
}
|
||||
|
||||
func (this *Skill) BeforeInsert() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
func (this *Skill) BeforeUpdate() {
|
||||
this.beforeModify()
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *Skill) IsCellView() bool{
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *Skill) IsCanView(rid, x, y int) bool{
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *Skill) BelongToRId() []int{
|
||||
return []int{this.RId}
|
||||
}
|
||||
|
||||
func (this *Skill) PushMsgName() string{
|
||||
return "skill.push"
|
||||
}
|
||||
|
||||
func (this *Skill) Position() (int, int){
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *Skill) TPosition() (int, int){
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *Skill) ToProto() interface{}{
|
||||
p := proto.Skill{}
|
||||
p.Id = this.Id
|
||||
p.CfgId = this.CfgId
|
||||
p.Generals = this.Generals
|
||||
return p
|
||||
}
|
||||
func (this *Skill) Push(){
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *Skill) SyncExecute() {
|
||||
dbSkillMgr.push(this)
|
||||
this.Push()
|
||||
}
|
||||
|
||||
func (this *Skill) Limit() int {
|
||||
cfg, _ := skill.Skill.GetCfg(this.CfgId)
|
||||
return cfg.Limit
|
||||
}
|
||||
|
||||
func (this *Skill) IsInLimit() bool{
|
||||
//fmt.Println("this.BelongGenerals", this.BelongGenerals)
|
||||
return len(this.Generals) < this.Limit()
|
||||
}
|
||||
|
||||
func (this *Skill) ArmyIsIn(armId int) bool {
|
||||
cfg, _ := skill.Skill.GetCfg(this.CfgId)
|
||||
for _, arm := range cfg.Arms {
|
||||
if arm == armId{
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *Skill) UpSkill(gId int) {
|
||||
this.Generals = append(this.Generals, gId)
|
||||
data, _ := json.Marshal(this.Generals)
|
||||
this.BelongGenerals = string(data)
|
||||
}
|
||||
|
||||
func (this *Skill) DownSkill(gId int) {
|
||||
gs := make([]int, 0)
|
||||
for _, general := range this.Generals {
|
||||
if gId != general {
|
||||
gs = append(gs, general)
|
||||
}
|
||||
}
|
||||
this.Generals = gs
|
||||
|
||||
data, _ := json.Marshal(this.Generals)
|
||||
this.BelongGenerals = string(data)
|
||||
}
|
||||
16
server/slgserver/model/util.go
Normal file
16
server/slgserver/model/util.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
var ArmyIsInView func(rid, x, y int) bool
|
||||
var GetUnionId func(rid int) int
|
||||
var GetUnionName func(unionId int) string
|
||||
var GetRoleNickName func(rid int) string
|
||||
var GetParentId func(rid int) int
|
||||
var GetMainMembers func(unionId int) []int
|
||||
var GetYield func(rid int) Yield
|
||||
var GetDepotCapacity func(rid int) int
|
||||
var GetCityCost func(cid int) int8
|
||||
var GetMaxDurable func(cid int) int
|
||||
var GetCityLv func(cid int) int8
|
||||
var MapResTypeLevel func(x, y int) (bool, int8, int8)
|
||||
|
||||
var ServerId = 0
|
||||
101
server/slgserver/model/war_report.go
Normal file
101
server/slgserver/model/war_report.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
type WarReport struct {
|
||||
Id int `xorm:"id pk autoincr"`
|
||||
AttackRid int `xorm:"a_rid"`
|
||||
DefenseRid int `xorm:"d_rid"`
|
||||
BegAttackArmy string `xorm:"b_a_army"`
|
||||
BegDefenseArmy string `xorm:"b_d_army"`
|
||||
EndAttackArmy string `xorm:"e_a_army"`
|
||||
EndDefenseArmy string `xorm:"e_d_army"`
|
||||
BegAttackGeneral string `xorm:"b_a_general"`
|
||||
BegDefenseGeneral string `xorm:"b_d_general"`
|
||||
EndAttackGeneral string `xorm:"e_a_general"`
|
||||
EndDefenseGeneral string `xorm:"e_d_general"`
|
||||
Result int `xorm:"result"` //0失败,1打平,2胜利
|
||||
Rounds string `xorm:"rounds"` //回合
|
||||
AttackIsRead bool `xorm:"a_is_read"`
|
||||
DefenseIsRead bool `xorm:"d_is_read"`
|
||||
DestroyDurable int `xorm:"destroy"`
|
||||
Occupy int `xorm:"occupy"`
|
||||
X int `xorm:"x"`
|
||||
Y int `xorm:"y"`
|
||||
CTime time.Time `xorm:"ctime"`
|
||||
}
|
||||
|
||||
func (this *WarReport) TableName() string {
|
||||
return "tb_war_report" + fmt.Sprintf("_%d", ServerId)
|
||||
}
|
||||
|
||||
/* 推送同步 begin */
|
||||
func (this *WarReport) IsCellView() bool{
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *WarReport) IsCanView(rid, x, y int) bool{
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *WarReport) BelongToRId() []int{
|
||||
return []int{this.AttackRid, this.DefenseRid}
|
||||
}
|
||||
|
||||
func (this *WarReport) PushMsgName() string{
|
||||
return "warReport.push"
|
||||
}
|
||||
|
||||
func (this *WarReport) Position() (int, int){
|
||||
return this.X, this.Y
|
||||
}
|
||||
|
||||
func (this *WarReport) TPosition() (int, int){
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (this *WarReport) ToProto() interface{}{
|
||||
p := proto.WarReport{}
|
||||
p.CTime = int(this.CTime.UnixNano() / 1e6)
|
||||
p.Id = this.Id
|
||||
p.AttackRid = this.AttackRid
|
||||
p.DefenseRid = this.DefenseRid
|
||||
p.BegAttackArmy = this.BegAttackArmy
|
||||
p.BegDefenseArmy = this.BegDefenseArmy
|
||||
p.EndAttackArmy = this.EndAttackArmy
|
||||
p.EndDefenseArmy = this.EndDefenseArmy
|
||||
p.BegAttackGeneral = this.BegAttackGeneral
|
||||
p.BegDefenseGeneral = this.BegDefenseGeneral
|
||||
p.EndAttackGeneral = this.EndAttackGeneral
|
||||
p.EndDefenseGeneral = this.EndDefenseGeneral
|
||||
p.Result = this.Result
|
||||
p.Rounds = this.Rounds
|
||||
p.AttackIsRead = this.AttackIsRead
|
||||
p.DefenseIsRead = this.DefenseIsRead
|
||||
p.DestroyDurable = this.DestroyDurable
|
||||
p.Occupy = this.Occupy
|
||||
p.X = this.X
|
||||
p.X = this.X
|
||||
return p
|
||||
}
|
||||
|
||||
func (this *WarReport) Push(){
|
||||
net.ConnMgr.Push(this)
|
||||
}
|
||||
/* 推送同步 end */
|
||||
|
||||
func (this *WarReport) SyncExecute() {
|
||||
_, err := db.MasterDB.InsertOne(this)
|
||||
if err != nil{
|
||||
slog.Warn("db error", "error", err)
|
||||
}
|
||||
this.Push()
|
||||
}
|
||||
63
server/slgserver/pos/position.go
Normal file
63
server/slgserver/pos/position.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package pos
|
||||
|
||||
import "sync"
|
||||
|
||||
var RPMgr = RolePosMgr{
|
||||
posCaches: make(map[position]map[int]int),
|
||||
ridCaches: make(map[int]position),
|
||||
}
|
||||
|
||||
type position struct {
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
|
||||
type RolePosMgr struct {
|
||||
mutex sync.RWMutex
|
||||
posCaches map[position]map[int]int
|
||||
ridCaches map[int]position
|
||||
}
|
||||
|
||||
func (this *RolePosMgr) Push(x, y, rid int) {
|
||||
this.mutex.Lock()
|
||||
defer this.mutex.Unlock()
|
||||
|
||||
//旧的要删除
|
||||
if r, ok := this.ridCaches[rid]; ok {
|
||||
if r.X == x && r.Y == y{
|
||||
return
|
||||
}
|
||||
if c, ok1 := this.posCaches[r]; ok1 {
|
||||
delete(c, rid)
|
||||
}
|
||||
}
|
||||
|
||||
//新的写入
|
||||
p := position{x, y}
|
||||
_, ok := this.posCaches[p]
|
||||
if ok == false {
|
||||
this.posCaches[p] = make(map[int]int)
|
||||
}
|
||||
this.posCaches[p][rid] = rid
|
||||
this.ridCaches[rid] = p
|
||||
}
|
||||
|
||||
func (this *RolePosMgr) GetCellRoleIds(x, y, width, height int) []int{
|
||||
this.mutex.RLock()
|
||||
defer this.mutex.RUnlock()
|
||||
|
||||
l := make([]int, 0)
|
||||
for i := x-width; i <= x+width; i++ {
|
||||
for j := y-height; j <= y+height; j++ {
|
||||
pos := position{i, j}
|
||||
r, ok := this.posCaches[pos]
|
||||
if ok {
|
||||
for _, v := range r {
|
||||
l = append(l, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
36
server/slgserver/proto/city.go
Normal file
36
server/slgserver/proto/city.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package proto
|
||||
|
||||
type Facility struct {
|
||||
Name string `json:"name"`
|
||||
Level int8 `json:"level"`
|
||||
Type int8 `json:"type"`
|
||||
UpTime int64 `json:"up_time"` //升级的时间戳,0表示该等级已经升级完成了
|
||||
}
|
||||
|
||||
type FacilitiesReq struct {
|
||||
CityId int `json:"cityId"`
|
||||
}
|
||||
|
||||
type FacilitiesRsp struct {
|
||||
CityId int `json:"cityId"`
|
||||
Facilities []Facility `json:"facilities"`
|
||||
}
|
||||
|
||||
type UpFacilityReq struct {
|
||||
CityId int `json:"cityId"`
|
||||
FType int8 `json:"fType"`
|
||||
}
|
||||
|
||||
type UpFacilityRsp struct {
|
||||
CityId int `json:"cityId"`
|
||||
Facility Facility `json:"facility"`
|
||||
RoleRes RoleRes `json:"role_res"`
|
||||
}
|
||||
|
||||
type UpCityReq struct {
|
||||
CityId int `json:"cityId"`
|
||||
}
|
||||
|
||||
type UpCityRsp struct {
|
||||
City MapRoleCity `json:"city"`
|
||||
}
|
||||
195
server/slgserver/proto/coalition.go
Normal file
195
server/slgserver/proto/coalition.go
Normal file
@@ -0,0 +1,195 @@
|
||||
package proto
|
||||
|
||||
const (
|
||||
UnionChairman = 0 //盟主
|
||||
UnionViceChairman = 1 //副盟主
|
||||
UnionCommon = 2 //普通成员
|
||||
)
|
||||
|
||||
const (
|
||||
UnionUntreated = 0 //未处理
|
||||
UnionRefuse = 1 //拒绝
|
||||
UnionAdopt = 2 //通过
|
||||
)
|
||||
|
||||
type Member struct {
|
||||
RId int `json:"rid"`
|
||||
Name string `json:"name"`
|
||||
Title int8 `json:"title"`
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type Major struct {
|
||||
RId int `json:"rid"`
|
||||
Name string `json:"name"`
|
||||
Title int8 `json:"title"`
|
||||
}
|
||||
|
||||
|
||||
type Union struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
Name string `json:"name"` //联盟名字
|
||||
Cnt int `json:"cnt"` //联盟人数
|
||||
Notice string `json:"notice"` //公告
|
||||
Major []Major `json:"major"` //联盟主要人物,盟主副盟主
|
||||
}
|
||||
|
||||
type ApplyItem struct {
|
||||
Id int `json:"id"`
|
||||
RId int `json:"rid"`
|
||||
NickName string `json:"nick_name"`
|
||||
}
|
||||
|
||||
|
||||
//创建联盟
|
||||
type CreateReq struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type CreateRsp struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
//联盟列表
|
||||
type ListReq struct {
|
||||
}
|
||||
|
||||
type ListRsp struct {
|
||||
List []Union `json:"list"`
|
||||
}
|
||||
|
||||
//申请加入联盟
|
||||
type JoinReq struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
}
|
||||
|
||||
type JoinRsp struct {
|
||||
|
||||
}
|
||||
|
||||
//联盟成员
|
||||
type MemberReq struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
}
|
||||
|
||||
type MemberRsp struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
Members []Member `json:"Members"`
|
||||
}
|
||||
|
||||
|
||||
//获取申请列表
|
||||
type ApplyReq struct {
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
type ApplyRsp struct {
|
||||
Id int `json:"id"`
|
||||
Applys []ApplyItem `json:"applys"`
|
||||
}
|
||||
|
||||
//审核
|
||||
type VerifyReq struct {
|
||||
Id int `json:"id"` //申请操作的id
|
||||
Decide int8 `json:"decide"` //1是拒绝,2是通过
|
||||
}
|
||||
|
||||
type VerifyRsp struct {
|
||||
Id int `json:"id"` //申请操作的id
|
||||
Decide int8 `json:"decide"` //1是拒绝,2是通过
|
||||
}
|
||||
|
||||
//退出
|
||||
type ExitReq struct {
|
||||
|
||||
}
|
||||
|
||||
type ExitRsp struct {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//解散
|
||||
type DismissReq struct {
|
||||
|
||||
}
|
||||
|
||||
type DismissRsp struct {
|
||||
|
||||
}
|
||||
|
||||
|
||||
type NoticeReq struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
}
|
||||
|
||||
type NoticeRsp struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
//修改公告
|
||||
type ModNoticeReq struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type ModNoticeRsp struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
//踢人
|
||||
type KickReq struct {
|
||||
RId int `json:"rid"`
|
||||
}
|
||||
|
||||
type KickRsp struct {
|
||||
RId int `json:"rid"`
|
||||
}
|
||||
|
||||
//任命
|
||||
type AppointReq struct {
|
||||
RId int `json:"rid"`
|
||||
Title int `json:"title"` //职位,0盟主、1副盟主、2普通成员
|
||||
}
|
||||
|
||||
type AppointRsp struct {
|
||||
RId int `json:"rid"`
|
||||
Title int `json:"title"` //职位,0盟主、1副盟主、2普通成员
|
||||
}
|
||||
|
||||
//禅让(盟主副盟主)
|
||||
type AbdicateReq struct {
|
||||
RId int `json:"rid"` //禅让给的rid
|
||||
}
|
||||
|
||||
type AbdicateRsp struct {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//联盟信息
|
||||
type InfoReq struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
}
|
||||
|
||||
type InfoRsp struct {
|
||||
Id int `json:"id"` //联盟id
|
||||
Info Union `json:"info"`
|
||||
}
|
||||
|
||||
type UnionLog struct {
|
||||
OPRId int `json:"op_rid"`
|
||||
TargetId int `json:"target_id"`
|
||||
State int8 `json:"state"`
|
||||
Des string `json:"des"`
|
||||
Ctime int64 `json:"ctime"`
|
||||
}
|
||||
|
||||
type LogReq struct {
|
||||
}
|
||||
|
||||
type LogRsp struct {
|
||||
Logs []UnionLog `json:"logs"`
|
||||
}
|
||||
207
server/slgserver/proto/general.go
Normal file
207
server/slgserver/proto/general.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package proto
|
||||
|
||||
type GSkill struct {
|
||||
Id int `json:"id"`
|
||||
Lv int `json:"lv"`
|
||||
CfgId int `json:"cfgId"`
|
||||
}
|
||||
type General struct {
|
||||
Id int `json:"id"`
|
||||
CfgId int `json:"cfgId"`
|
||||
PhysicalPower int `json:"physical_power"`
|
||||
Order int8 `json:"order"`
|
||||
Level int8 `json:"level"`
|
||||
Exp int `json:"exp"`
|
||||
CityId int `json:"cityId"`
|
||||
CurArms int `json:"curArms"`
|
||||
HasPrPoint int `json:"hasPrPoint"`
|
||||
UsePrPoint int `json:"usePrPoint"`
|
||||
AttackDis int `json:"attack_distance"`
|
||||
ForceAdded int `json:"force_added"`
|
||||
StrategyAdded int `json:"strategy_added"`
|
||||
DefenseAdded int `json:"defense_added"`
|
||||
SpeedAdded int `json:"speed_added"`
|
||||
DestroyAdded int `json:"destroy_added"`
|
||||
StarLv int8 `json:"star_lv"`
|
||||
Star int8 `json:"star"`
|
||||
ParentId int `json:"parentId"`
|
||||
Skills []*GSkill `json:"skills"`
|
||||
State int8 `json:"state"`
|
||||
|
||||
}
|
||||
|
||||
func (this*General) ToArray()[]int {
|
||||
r := make([]int, 0)
|
||||
|
||||
r = append(r, this.Id)
|
||||
r = append(r, this.CfgId)
|
||||
r = append(r, this.PhysicalPower)
|
||||
r = append(r, int(this.Order))
|
||||
r = append(r, int(this.Level))
|
||||
r = append(r, this.Exp)
|
||||
r = append(r, this.CityId)
|
||||
r = append(r, this.CurArms)
|
||||
r = append(r, this.HasPrPoint)
|
||||
r = append(r, this.UsePrPoint)
|
||||
r = append(r, this.AttackDis)
|
||||
r = append(r, this.ForceAdded)
|
||||
r = append(r, this.StrategyAdded)
|
||||
r = append(r, this.SpeedAdded)
|
||||
r = append(r, this.DefenseAdded)
|
||||
r = append(r, this.DestroyAdded)
|
||||
r = append(r, int(this.StarLv))
|
||||
r = append(r, int(this.Star))
|
||||
return r
|
||||
}
|
||||
|
||||
type MyGeneralReq struct {
|
||||
|
||||
}
|
||||
|
||||
type MyGeneralRsp struct {
|
||||
Generals []General `json:"generals"`
|
||||
}
|
||||
|
||||
|
||||
type ArmyListReq struct {
|
||||
CityId int `json:"cityId"`
|
||||
}
|
||||
|
||||
type ArmyListRsp struct {
|
||||
CityId int `json:"cityId"`
|
||||
Armys []Army `json:"armys"`
|
||||
}
|
||||
|
||||
|
||||
type ArmyOneReq struct {
|
||||
CityId int `json:"cityId"`
|
||||
Order int8 `json:"order"`
|
||||
}
|
||||
|
||||
type ArmyOneRsp struct {
|
||||
Army Army `json:"army"`
|
||||
}
|
||||
|
||||
type Army struct {
|
||||
Id int `json:"id"`
|
||||
CityId int `json:"cityId"`
|
||||
UnionId int `json:"union_id"` //联盟id
|
||||
Order int8 `json:"order"` //第几队,1-5队
|
||||
Generals []int `json:"generals"`
|
||||
Soldiers []int `json:"soldiers"`
|
||||
ConTimes []int64 `json:"con_times"`
|
||||
ConCnts []int `json:"con_cnts"`
|
||||
Cmd int8 `json:"cmd"`
|
||||
State int8 `json:"state"` //状态:0:running,1:stop
|
||||
FromX int `json:"from_x"`
|
||||
FromY int `json:"from_y"`
|
||||
ToX int `json:"to_x"`
|
||||
ToY int `json:"to_y"`
|
||||
Start int64 `json:"start"`//出征开始时间
|
||||
End int64 `json:"end"`//出征结束时间
|
||||
}
|
||||
|
||||
//配置武将
|
||||
type DisposeReq struct {
|
||||
CityId int `json:"cityId"` //城市id
|
||||
GeneralId int `json:"generalId"` //将领id
|
||||
Order int8 `json:"order"` //第几队,1-5队
|
||||
Position int `json:"position"` //位置,-1到2,-1是解除该武将上阵状态
|
||||
}
|
||||
|
||||
type DisposeRsp struct {
|
||||
Army Army `json:"army"`
|
||||
}
|
||||
|
||||
//征兵
|
||||
type ConscriptReq struct {
|
||||
ArmyId int `json:"armyId"` //队伍id
|
||||
Cnts []int `json:"cnts"` //征兵人数
|
||||
}
|
||||
|
||||
type ConscriptRsp struct {
|
||||
Army Army `json:"army"`
|
||||
RoleRes RoleRes `json:"role_res"`
|
||||
}
|
||||
|
||||
//派遣队伍
|
||||
type AssignArmyReq struct {
|
||||
ArmyId int `json:"armyId"` //队伍id
|
||||
Cmd int8 `json:"cmd"` //命令:0:空闲 1:攻击 2:驻军 3:返回
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type AssignArmyRsp struct {
|
||||
Army Army `json:"army"`
|
||||
}
|
||||
|
||||
|
||||
//抽卡
|
||||
type DrawGeneralReq struct {
|
||||
DrawTimes int `json:"drawTimes"` //抽卡次数
|
||||
}
|
||||
|
||||
type DrawGeneralRsp struct {
|
||||
Generals []General `json:"generals"`
|
||||
}
|
||||
|
||||
|
||||
|
||||
//合成
|
||||
type ComposeGeneralReq struct {
|
||||
CompId int `json:"compId"`
|
||||
GIds []int `json:"gIds"` //合成材料
|
||||
}
|
||||
|
||||
type ComposeGeneralRsp struct {
|
||||
Generals []General `json:"generals"`
|
||||
}
|
||||
|
||||
//加点
|
||||
type AddPrGeneralReq struct {
|
||||
CompId int `json:"compId"`
|
||||
ForceAdd int `json:"forceAdd"`
|
||||
StrategyAdd int `json:"strategyAdd"`
|
||||
DefenseAdd int `json:"defenseAdd"`
|
||||
SpeedAdd int `json:"speedAdd"`
|
||||
DestroyAdd int `json:"destroyAdd"`
|
||||
}
|
||||
|
||||
type AddPrGeneralRsp struct {
|
||||
Generals General `json:"general"`
|
||||
}
|
||||
|
||||
type ConvertReq struct {
|
||||
GIds []int `json:"gIds"`
|
||||
}
|
||||
|
||||
type ConvertRsp struct {
|
||||
GIds []int `json:"gIds"`
|
||||
Gold int `json:"gold"`
|
||||
AddGold int `json:"add_gold"`
|
||||
}
|
||||
|
||||
type UpDownSkillReq struct {
|
||||
GId int `json:"gId"` //武将id
|
||||
CfgId int `json:"cfgId"` //技能配置id
|
||||
Pos int `json:"pos"` //位置0-2
|
||||
}
|
||||
|
||||
type UpDownSkillRsp struct {
|
||||
GId int `json:"gId"` //武将id
|
||||
CfgId int `json:"cfgId"` //技能配置id
|
||||
Pos int `json:"pos"` //位置0-2
|
||||
}
|
||||
|
||||
|
||||
type LvSkillReq struct {
|
||||
GId int `json:"gId"` //武将id
|
||||
Pos int `json:"pos"` //位置0-2
|
||||
}
|
||||
|
||||
type LvSkillRsp struct {
|
||||
GId int `json:"gId"` //武将id
|
||||
Pos int `json:"pos"` //位置0-2
|
||||
}
|
||||
|
||||
29
server/slgserver/proto/interior.go
Normal file
29
server/slgserver/proto/interior.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package proto
|
||||
|
||||
type CollectionReq struct {
|
||||
}
|
||||
|
||||
type CollectionRsp struct {
|
||||
Gold int `json:"gold"`
|
||||
Limit int8 `json:"limit"`
|
||||
CurTimes int8 `json:"cur_times"`
|
||||
NextTime int64 `json:"next_time"`
|
||||
}
|
||||
|
||||
type OpenCollectionReq struct {
|
||||
}
|
||||
|
||||
type OpenCollectionRsp struct {
|
||||
Limit int8 `json:"limit"`
|
||||
CurTimes int8 `json:"cur_times"`
|
||||
NextTime int64 `json:"next_time"`
|
||||
}
|
||||
|
||||
type TransformReq struct {
|
||||
From []int `json:"from"` //0 Wood 1 Iron 2 Stone 3 Grain
|
||||
To []int `json:"to"` //0 Wood 1 Iron 2 Stone 3 Grain
|
||||
}
|
||||
|
||||
type TransformRsp struct {
|
||||
}
|
||||
|
||||
104
server/slgserver/proto/nation_map.go
Normal file
104
server/slgserver/proto/nation_map.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package proto
|
||||
|
||||
type Conf struct {
|
||||
Type int8 `json:"type"`
|
||||
Level int8 `json:"level"`
|
||||
Name string `json:"name"`
|
||||
Wood int `json:"Wood"`
|
||||
Iron int `json:"iron"`
|
||||
Stone int `json:"stone"`
|
||||
Grain int `json:"grain"`
|
||||
Durable int `json:"durable"` //耐久
|
||||
Defender int `json:"defender"` //防御等级
|
||||
}
|
||||
|
||||
type ConfigReq struct {
|
||||
|
||||
}
|
||||
|
||||
type ConfigRsp struct {
|
||||
Confs []Conf
|
||||
}
|
||||
|
||||
|
||||
type MapRoleBuild struct {
|
||||
RId int `json:"rid"`
|
||||
RNick string `json:"RNick"` //角色昵称
|
||||
Name string `json:"name"`
|
||||
UnionId int `json:"union_id"` //联盟id
|
||||
UnionName string `json:"union_name"` //联盟名字
|
||||
ParentId int `json:"parent_id"` //上级id
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Type int8 `json:"type"`
|
||||
Level int8 `json:"level"`
|
||||
OPLevel int8 `json:"op_level"`
|
||||
CurDurable int `json:"cur_durable"`
|
||||
MaxDurable int `json:"max_durable"`
|
||||
Defender int `json:"defender"`
|
||||
OccupyTime int64 `json:"occupy_time"`
|
||||
EndTime int64 `json:"end_time"` //建造完的时间
|
||||
GiveUpTime int64 `json:"giveUp_time"` //领地到了这个时间会被放弃
|
||||
}
|
||||
|
||||
|
||||
type ScanReq struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type ScanRsp struct {
|
||||
MRBuilds []MapRoleBuild `json:"mr_builds"` //角色建筑,包含被占领的基础建筑
|
||||
MCBuilds []MapRoleCity `json:"mc_builds"` //角色城市
|
||||
Armys []Army `json:"armys"` //军队
|
||||
}
|
||||
|
||||
type ScanBlockReq struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Length int `json:"length"`
|
||||
}
|
||||
|
||||
type GiveUpReq struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type GiveUpRsp struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type BuildReq struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Type int8 `json:"type"`
|
||||
}
|
||||
|
||||
type BuildRsp struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Type int8 `json:"type"`
|
||||
}
|
||||
|
||||
type UpBuildReq struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type UpBuildRsp struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Build MapRoleBuild `json:"build"`
|
||||
}
|
||||
|
||||
type DelBuildReq struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type DelBuildRsp struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Build MapRoleBuild `json:"build"`
|
||||
}
|
||||
154
server/slgserver/proto/role.go
Normal file
154
server/slgserver/proto/role.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package proto
|
||||
|
||||
type Role struct {
|
||||
RId int `json:"rid"`
|
||||
UId int `json:"uid"`
|
||||
NickName string `json:"nickName"`
|
||||
Sex int8 `json:"sex"`
|
||||
Balance int `json:"balance"`
|
||||
HeadId int16 `json:"headId"`
|
||||
Profile string `json:"profile"`
|
||||
}
|
||||
|
||||
type RoleRes struct {
|
||||
Wood int `json:"wood"`
|
||||
Iron int `json:"iron"`
|
||||
Stone int `json:"stone"`
|
||||
Grain int `json:"grain"`
|
||||
Gold int `json:"gold"`
|
||||
Decree int `json:"decree"` //令牌
|
||||
WoodYield int `json:"wood_yield"`
|
||||
IronYield int `json:"iron_yield"`
|
||||
StoneYield int `json:"stone_yield"`
|
||||
GrainYield int `json:"grain_yield"`
|
||||
GoldYield int `json:"gold_yield"`
|
||||
DepotCapacity int `json:"depot_capacity"` //仓库容量
|
||||
}
|
||||
|
||||
type CreateRoleReq struct {
|
||||
UId int `json:"uid"`
|
||||
NickName string `json:"nickName"`
|
||||
Sex int8 `json:"sex"`
|
||||
SId int `json:"sid"`
|
||||
HeadId int16 `json:"headId"`
|
||||
}
|
||||
|
||||
type CreateRoleRsp struct {
|
||||
Role Role `json:"role"`
|
||||
}
|
||||
|
||||
type RoleListReq struct {
|
||||
UId int `json:"uid"`
|
||||
}
|
||||
|
||||
type RoleListRsp struct {
|
||||
Roles []Role
|
||||
}
|
||||
|
||||
type EnterServerReq struct {
|
||||
Session string `json:"session"`
|
||||
}
|
||||
|
||||
type EnterServerRsp struct {
|
||||
Role Role `json:"role"`
|
||||
RoleRes RoleRes `json:"role_res"`
|
||||
Time int64 `json:"time"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type MapRoleCity struct {
|
||||
CityId int `json:"cityId"`
|
||||
RId int `json:"rid"`
|
||||
Name string `json:"name"`
|
||||
UnionId int `json:"union_id"` //联盟id
|
||||
UnionName string `json:"union_name"` //联盟名字
|
||||
ParentId int `json:"parent_id"` //上级id
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
IsMain bool `json:"is_main"`
|
||||
Level int8 `json:"level"`
|
||||
CurDurable int `json:"cur_durable"`
|
||||
MaxDurable int `json:"max_durable"`
|
||||
OccupyTime int64 `json:"occupy_time"`
|
||||
}
|
||||
|
||||
type MyCityReq struct {
|
||||
|
||||
}
|
||||
|
||||
type MyCityRsp struct {
|
||||
Citys []MapRoleCity `json:"citys"`
|
||||
}
|
||||
|
||||
type MyRoleResReq struct {
|
||||
|
||||
}
|
||||
|
||||
type MyRoleResRsp struct {
|
||||
RoleRes RoleRes `json:"role_res"`
|
||||
}
|
||||
|
||||
type MyRoleBuildReq struct {
|
||||
|
||||
}
|
||||
|
||||
type MyRoleBuildRsp struct {
|
||||
MRBuilds []MapRoleBuild `json:"mr_builds"` //角色建筑,包含被占领的基础建筑
|
||||
}
|
||||
|
||||
/*
|
||||
建筑发生变化
|
||||
*/
|
||||
type RoleBuildStatePush struct {
|
||||
MRBuild MapRoleBuild `json:"mr_build"` //角色建筑,包含被占领的基础建筑
|
||||
}
|
||||
|
||||
type MyRolePropertyReq struct {
|
||||
|
||||
}
|
||||
|
||||
type MyRolePropertyRsp struct {
|
||||
RoleRes RoleRes `json:"role_res"`
|
||||
MRBuilds []MapRoleBuild `json:"mr_builds"` //角色建筑,包含被占领的基础建筑
|
||||
Generals []General `json:"generals"`
|
||||
Citys []MapRoleCity `json:"citys"`
|
||||
Armys []Army `json:"armys"`
|
||||
}
|
||||
|
||||
type UpPositionReq struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type UpPositionRsp struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type PosTag struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type PosTagListReq struct {
|
||||
|
||||
}
|
||||
|
||||
type PosTagListRsp struct {
|
||||
PosTags []PosTag `json:"pos_tags"`
|
||||
}
|
||||
|
||||
type PosTagReq struct {
|
||||
Type int `json:"type"` //1是标记,0是取消标记
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type PosTagRsp struct {
|
||||
Type int `json:"type"` //1是标记,0是取消标记
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
16
server/slgserver/proto/skill.go
Normal file
16
server/slgserver/proto/skill.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package proto
|
||||
|
||||
|
||||
type Skill struct {
|
||||
Id int `json:"id"`
|
||||
CfgId int `json:"cfgId"`
|
||||
Generals []int `json:"generals"`
|
||||
}
|
||||
|
||||
type SkillListReq struct {
|
||||
|
||||
}
|
||||
|
||||
type SkillListRsp struct {
|
||||
List []Skill `json:"list"`
|
||||
}
|
||||
45
server/slgserver/proto/war.go
Normal file
45
server/slgserver/proto/war.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package proto
|
||||
|
||||
type WarReport struct {
|
||||
Id int `json:"id"`
|
||||
AttackRid int `json:"a_rid"`
|
||||
DefenseRid int `json:"d_rid"`
|
||||
BegAttackArmy string `json:"b_a_army"`
|
||||
BegDefenseArmy string `json:"b_d_army"`
|
||||
EndAttackArmy string `json:"e_a_army"`
|
||||
EndDefenseArmy string `json:"e_d_army"`
|
||||
BegAttackGeneral string `json:"b_a_general"`
|
||||
BegDefenseGeneral string `json:"b_d_general"`
|
||||
EndAttackGeneral string `json:"e_a_general"`
|
||||
EndDefenseGeneral string `json:"e_d_general"`
|
||||
Result int `json:"result"` //0失败,1打平,2胜利
|
||||
Rounds string `json:"rounds"` //回合
|
||||
AttackIsRead bool `json:"a_is_read"`
|
||||
DefenseIsRead bool `json:"d_is_read"`
|
||||
DestroyDurable int `json:"destroy"`
|
||||
Occupy int `json:"occupy"`
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
CTime int `json:"ctime"`
|
||||
}
|
||||
|
||||
|
||||
type WarReportPush struct {
|
||||
List []WarReport `json:"list"`
|
||||
}
|
||||
|
||||
type WarReportReq struct {
|
||||
|
||||
}
|
||||
|
||||
type WarReportRsp struct {
|
||||
List []WarReport `json:"list"`
|
||||
}
|
||||
|
||||
type WarReadReq struct {
|
||||
Id uint `json:"id"` //0全部已读
|
||||
}
|
||||
|
||||
type WarReadRsp struct {
|
||||
Id uint `json:"id"`
|
||||
}
|
||||
65
server/slgserver/run/init.go
Normal file
65
server/slgserver/run/init.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package run
|
||||
|
||||
import (
|
||||
"slgserver/config"
|
||||
"slgserver/db"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/controller"
|
||||
"slgserver/server/slgserver/logic"
|
||||
"slgserver/server/slgserver/logic/mgr"
|
||||
"slgserver/server/slgserver/model"
|
||||
"slgserver/server/slgserver/static_conf"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
"slgserver/server/slgserver/static_conf/general"
|
||||
"slgserver/server/slgserver/static_conf/skill"
|
||||
)
|
||||
|
||||
var MyRouter = &net.Router{}
|
||||
|
||||
func Init() {
|
||||
db.TestDB()
|
||||
|
||||
facility.FConf.Load()
|
||||
general.GenBasic.Load()
|
||||
skill.Skill.Load()
|
||||
|
||||
general.General.Load()
|
||||
static_conf.Basic.Load()
|
||||
static_conf.MapBuildConf.Load()
|
||||
static_conf.MapBCConf.Load()
|
||||
|
||||
serverId := config.GetInt("logic.server_id", 1)
|
||||
model.ServerId = serverId
|
||||
|
||||
logic.BeforeInit()
|
||||
|
||||
mgr.NMMgr.Load()
|
||||
//需要先加载联盟相关的信息
|
||||
mgr.UnionMgr.Load()
|
||||
mgr.RAttrMgr.Load()
|
||||
mgr.RCMgr.Load()
|
||||
mgr.RBMgr.Load()
|
||||
mgr.RFMgr.Load()
|
||||
mgr.RResMgr.Load()
|
||||
mgr.SkillMgr.Load()
|
||||
mgr.GMgr.Load()
|
||||
mgr.AMgr.Load()
|
||||
logic.Init()
|
||||
logic.AfterInit()
|
||||
|
||||
//全部初始化完才注册路由,防止服务器还没启动就绪收到请求
|
||||
initRouter()
|
||||
}
|
||||
|
||||
func initRouter() {
|
||||
|
||||
controller.DefaultRole.InitRouter(MyRouter)
|
||||
controller.DefaultMap.InitRouter(MyRouter)
|
||||
controller.DefaultCity.InitRouter(MyRouter)
|
||||
controller.DefaultGeneral.InitRouter(MyRouter)
|
||||
controller.DefaultArmy.InitRouter(MyRouter)
|
||||
controller.DefaultWar.InitRouter(MyRouter)
|
||||
controller.DefaultCoalition.InitRouter(MyRouter)
|
||||
controller.DefaultInterior.InitRouter(MyRouter)
|
||||
controller.DefaultSkill.InitRouter(MyRouter)
|
||||
}
|
||||
119
server/slgserver/static_conf/basic.go
Normal file
119
server/slgserver/static_conf/basic.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package static_conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
)
|
||||
|
||||
var Basic basic
|
||||
|
||||
type conscript struct {
|
||||
Des string `json:"des"`
|
||||
CostWood int `json:"cost_wood"`
|
||||
CostIron int `json:"cost_iron"`
|
||||
CostStone int `json:"cost_stone"`
|
||||
CostGrain int `json:"cost_grain"`
|
||||
CostGold int `json:"cost_gold"`
|
||||
CostTime int `json:"cost_time"` //每征一个兵需要花费时间
|
||||
}
|
||||
|
||||
type general struct {
|
||||
Des string `json:"des"`
|
||||
PhysicalPowerLimit int `json:"physical_power_limit"` //体力上限
|
||||
CostPhysicalPower int `json:"cost_physical_power"` //消耗体力
|
||||
RecoveryPhysicalPower int `json:"recovery_physical_power"` //恢复体力
|
||||
ReclamationTime int `json:"reclamation_time"` //屯田消耗时间,单位秒
|
||||
ReclamationCost int `json:"reclamation_cost"` //屯田消耗政令
|
||||
DrawGeneralCost int `json:"draw_general_cost"` //抽卡消耗金币
|
||||
PrPoint int `json:"pr_point"` //合成一个武将或者的技能点
|
||||
Limit int `json:"limit"` //武将数量上限
|
||||
|
||||
}
|
||||
|
||||
type role struct {
|
||||
Des string `json:"des"`
|
||||
Wood int `json:"wood"`
|
||||
Iron int `json:"iron"`
|
||||
Stone int `json:"stone"`
|
||||
Grain int `json:"grain"`
|
||||
Gold int `json:"gold"`
|
||||
Decree int `json:"decree"`
|
||||
WoodYield int `json:"wood_yield"`
|
||||
IronYield int `json:"iron_yield"`
|
||||
StoneYield int `json:"stone_yield"`
|
||||
GrainYield int `json:"grain_yield"`
|
||||
GoldYield int `json:"gold_yield"`
|
||||
DepotCapacity int `json:"depot_capacity"` //仓库初始容量
|
||||
BuildLimit int `json:"build_limit"` //野外建筑上限
|
||||
RecoveryTime int `json:"recovery_time"`
|
||||
DecreeLimit int `json:"decree_limit"` //令牌上限
|
||||
CollectTimesLimit int8 `json:"collect_times_limit"` //每日征收次数上限
|
||||
CollectInterval int `json:"collect_interval"` //征收间隔
|
||||
PosTagLimit int8 `json:"pos_tag_limit"` //位置标签上限
|
||||
}
|
||||
|
||||
type city struct {
|
||||
Des string `json:"des"`
|
||||
Cost int8 `json:"cost"`
|
||||
Durable int `json:"durable"`
|
||||
RecoveryTime int `json:"recovery_time"`
|
||||
TransformRate int `json:"transform_rate"`
|
||||
}
|
||||
|
||||
type build struct {
|
||||
Des string `json:"des"`
|
||||
WarFree int64 `json:"war_free"` //免战时间,单位秒
|
||||
GiveUpTime int64 `json:"giveUp_time"` //建筑放弃时间
|
||||
FortressLimit int `json:"fortress_limit"` //要塞上限
|
||||
}
|
||||
|
||||
type npcLevel struct {
|
||||
Soilders int `json:"soilders"`
|
||||
}
|
||||
|
||||
type npc struct {
|
||||
Des string `json:"des"`
|
||||
Levels []npcLevel `json:"levels"`
|
||||
}
|
||||
|
||||
type union struct {
|
||||
Des string `json:"des"`
|
||||
MemberLimit int `json:"member_limit"`
|
||||
}
|
||||
|
||||
type basic struct {
|
||||
ConScript conscript `json:"conscript"`
|
||||
General general `json:"general"`
|
||||
Role role `json:"role"`
|
||||
City city `json:"city"`
|
||||
Npc npc `json:"npc"`
|
||||
Union union `json:"union"`
|
||||
Build build `json:"build"`
|
||||
}
|
||||
|
||||
func (this *basic) Load() {
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "basic.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("basic load file error", "error", err, "file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
|
||||
slog.Debug("basic config loaded")
|
||||
}
|
||||
|
||||
func (this *basic) GetNPC(level int8) (*npcLevel, bool) {
|
||||
if level <= 0 {
|
||||
return nil, false
|
||||
}
|
||||
if len(this.Npc.Levels) >= int(level) {
|
||||
return &this.Npc.Levels[level-1], true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
58
server/slgserver/static_conf/facility/facility.go
Normal file
58
server/slgserver/static_conf/facility/facility.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package facility
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
)
|
||||
|
||||
type conditions struct {
|
||||
Type int `json:"type"`
|
||||
Level int `json:"level"`
|
||||
}
|
||||
|
||||
type facility struct {
|
||||
Title string `json:"title"`
|
||||
Des string `json:"des"`
|
||||
Name string `json:"name"`
|
||||
Type int8 `json:"type"`
|
||||
Additions []int8 `json:"additions"`
|
||||
Conditions []conditions `json:"conditions"`
|
||||
Levels []fLevel `json:"levels"`
|
||||
}
|
||||
|
||||
type NeedRes struct {
|
||||
Decree int `json:"decree"`
|
||||
Grain int `json:"grain"`
|
||||
Wood int `json:"wood"`
|
||||
Iron int `json:"iron"`
|
||||
Stone int `json:"stone"`
|
||||
Gold int `json:"gold"`
|
||||
}
|
||||
|
||||
type fLevel struct {
|
||||
Level int `json:"level"`
|
||||
Values []int `json:"values"`
|
||||
Need NeedRes `json:"need"`
|
||||
Time int `json:"time"` //升级需要的时间
|
||||
}
|
||||
|
||||
func NewFacility(jsonName string) *facility {
|
||||
f := &facility{}
|
||||
f.load(jsonName)
|
||||
return f
|
||||
}
|
||||
|
||||
func (this *facility) load(jsonName string) {
|
||||
|
||||
jdata, err := os.ReadFile(jsonName)
|
||||
if err != nil {
|
||||
slog.Error("facility load file error",
|
||||
"error", err, "file", jsonName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
|
||||
slog.Debug("facility file loaded", "name", this.Name)
|
||||
}
|
||||
31
server/slgserver/static_conf/facility/facility_addition.go
Normal file
31
server/slgserver/static_conf/facility/facility_addition.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package facility
|
||||
|
||||
|
||||
const (
|
||||
TypeDurable = 1 //耐久
|
||||
TypeCost = 2
|
||||
TypeArmyTeams = 3 //队伍数量
|
||||
TypeSpeed = 4 //速度
|
||||
TypeDefense = 5 //防御
|
||||
TypeStrategy = 6 //谋略
|
||||
TypeForce = 7 //攻击武力
|
||||
TypeConscriptTime = 8 //征兵时间
|
||||
TypeReserveLimit = 9 //预备役上限
|
||||
TypeUnkonw = 10
|
||||
TypeHanAddition = 11
|
||||
TypeQunAddition = 12
|
||||
TypeWeiAddition = 13
|
||||
TypeShuAddition = 14
|
||||
TypeWuAddition = 15
|
||||
TypeDealTaxRate = 16//交易税率
|
||||
TypeWood = 17
|
||||
TypeIron = 18
|
||||
TypeGrain = 19
|
||||
TypeStone = 20
|
||||
TypeTax = 21//税收
|
||||
TypeExtendTimes = 22//扩建次数
|
||||
TypeWarehouseLimit = 23//仓库容量
|
||||
TypeSoldierLimit = 24//带兵数量
|
||||
TypeVanguardLimit = 25//前锋数量
|
||||
)
|
||||
|
||||
134
server/slgserver/static_conf/facility/facility_conf.go
Normal file
134
server/slgserver/static_conf/facility/facility_conf.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package facility
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
)
|
||||
|
||||
const (
|
||||
Main = 0 //主城
|
||||
JiaoChang = 13 //校场
|
||||
TongShuaiTing = 14 //统帅厅
|
||||
JiShi = 15 //集市
|
||||
MBS = 16 //募兵所
|
||||
)
|
||||
|
||||
var FConf facilityConf
|
||||
|
||||
type conf struct {
|
||||
Name string
|
||||
Type int8
|
||||
}
|
||||
|
||||
type facilityConf struct {
|
||||
Title string `json:"title"`
|
||||
List []conf `json:"list"`
|
||||
facilitys map[int8]*facility
|
||||
}
|
||||
|
||||
func (this *facilityConf) Load() {
|
||||
this.facilitys = make(map[int8]*facility, 0)
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "facility", "facility.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("facilityConf load file error",
|
||||
"error", err,
|
||||
"file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
|
||||
fdir := path.Join(jsonDir, "facility")
|
||||
files, err := os.ReadDir(fdir)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
continue
|
||||
} else {
|
||||
if file.Name() == "facility.json" || file.Name() == "facility_addition.json" {
|
||||
continue
|
||||
}
|
||||
fileName := path.Join(fdir, file.Name())
|
||||
f := NewFacility(fileName)
|
||||
this.facilitys[f.Type] = f
|
||||
}
|
||||
}
|
||||
slog.Debug("facility config loaded", "count", len(this.facilitys))
|
||||
}
|
||||
|
||||
func (this *facilityConf) MaxLevel(fType int8) int8 {
|
||||
f, ok := this.facilitys[fType]
|
||||
if ok {
|
||||
return int8(len(f.Levels))
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (this *facilityConf) Need(fType int8, level int8) (*NeedRes, bool) {
|
||||
if level <= 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
f, ok := this.facilitys[fType]
|
||||
if ok {
|
||||
if int8(len(f.Levels)) >= level {
|
||||
return &f.Levels[level-1].Need, true
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
// 升级需要的时间
|
||||
func (this *facilityConf) CostTime(fType int8, level int8) int {
|
||||
if level <= 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
f, ok := this.facilitys[fType]
|
||||
if ok {
|
||||
if int8(len(f.Levels)) >= level {
|
||||
return f.Levels[level-1].Time - 2 //比客户端快2s,保证客户端倒计时完一定是升级成功了
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (this *facilityConf) GetValues(fType int8, level int8) []int {
|
||||
if level <= 0 {
|
||||
return []int{}
|
||||
}
|
||||
|
||||
f, ok := this.facilitys[fType]
|
||||
if ok {
|
||||
if int8(len(f.Levels)) >= level {
|
||||
return f.Levels[level-1].Values
|
||||
} else {
|
||||
return []int{}
|
||||
}
|
||||
} else {
|
||||
return []int{}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *facilityConf) GetAdditions(fType int8) []int8 {
|
||||
f, ok := this.facilitys[fType]
|
||||
if ok {
|
||||
return f.Additions
|
||||
} else {
|
||||
return []int8{}
|
||||
}
|
||||
}
|
||||
85
server/slgserver/static_conf/general/general.go
Normal file
85
server/slgserver/static_conf/general/general.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package general
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
"time"
|
||||
)
|
||||
|
||||
var General general
|
||||
|
||||
type g struct {
|
||||
Name string `json:"name"`
|
||||
CfgId int `json:"cfgId"`
|
||||
Force int `json:"force"`
|
||||
Strategy int `json:"strategy"`
|
||||
Defense int `json:"defense"`
|
||||
Speed int `json:"speed"`
|
||||
Destroy int `json:"destroy"`
|
||||
ForceGrow int `json:"force_grow"`
|
||||
StrategyGrow int `json:"strategy_grow"`
|
||||
DefenseGrow int `json:"defense_grow"`
|
||||
SpeedGrow int `json:"speed_grow"`
|
||||
DestroyGrow int `json:"destroy_grow"`
|
||||
Cost int8 `json:"cost"`
|
||||
Probability int `json:"probability"`
|
||||
Star int8 `json:"star"`
|
||||
Arms []int `json:"arms"`
|
||||
Camp int8 `json:"camp"`
|
||||
}
|
||||
|
||||
type general struct {
|
||||
Title string `json:"title"`
|
||||
GArr []g `json:"list"`
|
||||
GMap map[int]g
|
||||
totalProbability int
|
||||
}
|
||||
|
||||
func (this *general) Load() {
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "general", "general.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("general load file error",
|
||||
"error", err,
|
||||
"file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
this.totalProbability = 0
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
this.GMap = make(map[int]g)
|
||||
for _, v := range this.GArr {
|
||||
this.GMap[v.CfgId] = v
|
||||
this.totalProbability += v.Probability
|
||||
}
|
||||
slog.Debug("general config loaded", "count", len(this.GArr))
|
||||
}
|
||||
|
||||
func (this *general) Cost(cfgId int) int8 {
|
||||
c, ok := this.GMap[cfgId]
|
||||
if ok {
|
||||
return c.Cost
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (this *general) Draw() int {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
rate := rand.Intn(this.totalProbability)
|
||||
|
||||
cur := 0
|
||||
for _, g := range this.GArr {
|
||||
if rate >= cur && rate < cur+g.Probability {
|
||||
return g.CfgId
|
||||
}
|
||||
cur += g.Probability
|
||||
}
|
||||
return 0
|
||||
}
|
||||
67
server/slgserver/static_conf/general/general_arms.go
Normal file
67
server/slgserver/static_conf/general/general_arms.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package general
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
)
|
||||
|
||||
var GenArms Arms
|
||||
|
||||
type gArmsCondition struct {
|
||||
Level int `json:"level"`
|
||||
StarLevel int `json:"star_lv"`
|
||||
}
|
||||
|
||||
type gArmsCost struct {
|
||||
Gold int `json:"gold"`
|
||||
}
|
||||
|
||||
type gArms struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Condition gArmsCondition `json:"condition"`
|
||||
ChangeCost gArmsCost `json:"change_cost"`
|
||||
HarmRatio []int `json:"harm_ratio"`
|
||||
}
|
||||
|
||||
type Arms struct {
|
||||
Title string `json:"title"`
|
||||
Arms []gArms `json:"arms"`
|
||||
AMap map[int]gArms
|
||||
}
|
||||
|
||||
func (this *Arms) Load() {
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "general", "general_arms.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("general load file error", "error", err, "file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
|
||||
this.AMap = make(map[int]gArms)
|
||||
for _, v := range this.Arms {
|
||||
this.AMap[v.Id] = v
|
||||
}
|
||||
|
||||
slog.Debug("general arms loaded", "count", len(this.Arms))
|
||||
}
|
||||
|
||||
func (this *Arms) GetArm(id int) (gArms, error) {
|
||||
return this.AMap[id], nil
|
||||
}
|
||||
|
||||
func (this *Arms) GetHarmRatio(attId, defId int) float64 {
|
||||
attArm, ok1 := this.AMap[attId]
|
||||
_, ok2 := this.AMap[defId]
|
||||
if ok1 && ok2 {
|
||||
return float64(attArm.HarmRatio[defId-1]) / 100.0
|
||||
} else {
|
||||
return 1.0
|
||||
}
|
||||
}
|
||||
67
server/slgserver/static_conf/general/general_basic.go
Normal file
67
server/slgserver/static_conf/general/general_basic.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package general
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
)
|
||||
|
||||
var GenBasic Basic
|
||||
|
||||
type gLevel struct {
|
||||
Level int8 `json:"level"`
|
||||
Exp int `json:"exp"`
|
||||
Soldiers int `json:"soldiers"`
|
||||
}
|
||||
|
||||
type Basic struct {
|
||||
Title string `json:"title"`
|
||||
Levels []gLevel `json:"levels"`
|
||||
}
|
||||
|
||||
func (this *Basic) Load() {
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "general", "general_basic.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("general load file error", "error", err, "file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
|
||||
slog.Debug("general basic config loaded", "levels", len(this.Levels))
|
||||
|
||||
General.Load()
|
||||
GenArms.Load()
|
||||
}
|
||||
|
||||
func (this *Basic) GetLevel(l int8) (*gLevel, error) {
|
||||
if l <= 0 {
|
||||
return nil, errors.New("level error")
|
||||
}
|
||||
if int(l) <= len(this.Levels) {
|
||||
return &this.Levels[l-1], nil
|
||||
} else {
|
||||
return nil, errors.New("level error")
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Basic) ExpToLevel(exp int) (int8, int) {
|
||||
var level int8 = 0
|
||||
limitExp := this.Levels[len(this.Levels)-1].Exp
|
||||
for _, v := range this.Levels {
|
||||
if exp >= v.Exp && v.Level > level {
|
||||
level = v.Level
|
||||
}
|
||||
}
|
||||
|
||||
if limitExp < exp {
|
||||
return level, limitExp
|
||||
} else {
|
||||
return level, exp
|
||||
}
|
||||
}
|
||||
64
server/slgserver/static_conf/map_build.go
Normal file
64
server/slgserver/static_conf/map_build.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package static_conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
)
|
||||
|
||||
// 地图资源配置
|
||||
var MapBuildConf mapBuildConf
|
||||
|
||||
type cfg struct {
|
||||
Type int8 `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Level int8 `json:"level"`
|
||||
Grain int `json:"grain"`
|
||||
Wood int `json:"wood"`
|
||||
Iron int `json:"iron"`
|
||||
Stone int `json:"stone"`
|
||||
Durable int `json:"durable"`
|
||||
Defender int `json:"defender"`
|
||||
}
|
||||
|
||||
type mapBuildConf struct {
|
||||
Title string `json:"title"`
|
||||
Cfg []cfg `json:"cfg"`
|
||||
cfgMap map[int8][]cfg
|
||||
}
|
||||
|
||||
func (this *mapBuildConf) Load() {
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "map_build.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("mapBuildConf load file error", "error", err, "file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
|
||||
this.cfgMap = make(map[int8][]cfg)
|
||||
for _, v := range this.Cfg {
|
||||
if _, ok := this.cfgMap[v.Type]; ok == false {
|
||||
this.cfgMap[v.Type] = make([]cfg, 0)
|
||||
}
|
||||
this.cfgMap[v.Type] = append(this.cfgMap[v.Type], v)
|
||||
}
|
||||
|
||||
slog.Debug("map build config loaded", "types", len(this.cfgMap))
|
||||
}
|
||||
|
||||
func (this *mapBuildConf) BuildConfig(cfgType int8, level int8) (*cfg, bool) {
|
||||
if c, ok := this.cfgMap[cfgType]; ok {
|
||||
for _, v := range c {
|
||||
if v.Level == level {
|
||||
return &v, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
94
server/slgserver/static_conf/map_build_custom.go
Normal file
94
server/slgserver/static_conf/map_build_custom.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package static_conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
"slgserver/server/slgserver/static_conf/facility"
|
||||
)
|
||||
|
||||
// 地图资源配置
|
||||
var MapBCConf mapBuildCustomConf
|
||||
|
||||
type level struct {
|
||||
Level int8 `json:"level"`
|
||||
Time int `json:"time"` //升级需要的时间
|
||||
Durable int `json:"durable"`
|
||||
Defender int `json:"defender"`
|
||||
Need facility.NeedRes `json:"need"`
|
||||
Result result `json:"result"`
|
||||
}
|
||||
|
||||
type customConf struct {
|
||||
Type int8 `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Levels []level `json:"levels"`
|
||||
}
|
||||
|
||||
type result struct {
|
||||
ArmyCnt int `json:"army_cnt"`
|
||||
}
|
||||
|
||||
type BCLevelCfg struct {
|
||||
level
|
||||
Type int8 `json:"type"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type mapBuildCustomConf struct {
|
||||
Title string `json:"title"`
|
||||
Cfg []customConf `json:"cfg"`
|
||||
cfgMap map[int8]customConf
|
||||
}
|
||||
|
||||
func (this *mapBuildCustomConf) Load() {
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "map_build_custom.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("mapBuildCustomConf load file error",
|
||||
"error", err,
|
||||
"file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, this)
|
||||
|
||||
this.cfgMap = make(map[int8]customConf)
|
||||
for _, v := range this.Cfg {
|
||||
this.cfgMap[v.Type] = v
|
||||
}
|
||||
|
||||
slog.Debug("map build custom config loaded", "types", len(this.cfgMap))
|
||||
}
|
||||
|
||||
func (this *mapBuildCustomConf) BuildConfig(cfgType int8, level int8) (*BCLevelCfg, bool) {
|
||||
if c, ok := this.cfgMap[cfgType]; ok {
|
||||
if len(c.Levels) < int(level) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
lc := c.Levels[level-1]
|
||||
cfg := BCLevelCfg{Type: cfgType, Name: c.Name}
|
||||
cfg.Level = level
|
||||
cfg.Need = lc.Need
|
||||
cfg.Result = lc.Result
|
||||
cfg.Durable = lc.Durable
|
||||
cfg.Time = lc.Time
|
||||
cfg.Result = lc.Result
|
||||
|
||||
return &cfg, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// 可容纳队伍数量
|
||||
func (this *mapBuildCustomConf) GetHoldArmyCnt(cfgType int8, level int8) int {
|
||||
cfg, ok := this.BuildConfig(cfgType, level)
|
||||
if ok == false {
|
||||
return 0
|
||||
}
|
||||
return cfg.Result.ArmyCnt
|
||||
}
|
||||
73
server/slgserver/static_conf/skill/skill.go
Normal file
73
server/slgserver/static_conf/skill/skill.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package skill
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"slgserver/config"
|
||||
)
|
||||
|
||||
var Skill skill
|
||||
|
||||
type skill struct {
|
||||
skills []Conf
|
||||
skillConfMap map[int]Conf
|
||||
outline outline
|
||||
}
|
||||
|
||||
func (this *skill) Load() {
|
||||
this.skills = make([]Conf, 0)
|
||||
this.skillConfMap = make(map[int]Conf)
|
||||
|
||||
jsonDir := config.GetPath("logic.json_data", "data/conf/json/")
|
||||
fileName := path.Join(jsonDir, "skill", "skill_outline.json")
|
||||
jdata, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
slog.Error("skill load file error", "error", err, "file", fileName)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
json.Unmarshal(jdata, &this.outline)
|
||||
|
||||
rd, err := os.ReadDir(path.Join(jsonDir, "skill"))
|
||||
if err != nil {
|
||||
slog.Error("skill readdir error", "error", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
for _, r := range rd {
|
||||
if r.IsDir() {
|
||||
this.readSkill(path.Join(jsonDir, "skill", r.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
slog.Debug("skill configs loaded", "count", len(this.skills))
|
||||
}
|
||||
|
||||
func (this *skill) readSkill(dir string) {
|
||||
rd, err := os.ReadDir(dir)
|
||||
if err == nil {
|
||||
for _, r := range rd {
|
||||
if r.IsDir() == false {
|
||||
jdata, err := os.ReadFile(path.Join(dir, r.Name()))
|
||||
if err == nil {
|
||||
conf := Conf{}
|
||||
if err := json.Unmarshal(jdata, &conf); err == nil {
|
||||
this.skills = append(this.skills, conf)
|
||||
this.skillConfMap[conf.CfgId] = conf
|
||||
} else {
|
||||
slog.Warn("Unmarshal skill error", "error", err,
|
||||
"file", path.Join(dir, r.Name()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *skill) GetCfg(cfgId int) (Conf, bool) {
|
||||
cfg, ok := this.skillConfMap[cfgId]
|
||||
return cfg, ok
|
||||
}
|
||||
19
server/slgserver/static_conf/skill/skill_conf.go
Normal file
19
server/slgserver/static_conf/skill/skill_conf.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package skill
|
||||
|
||||
type level struct {
|
||||
Probability int `json:"probability"` //发动概率
|
||||
EffectValue []int `json:"effect_value"` //效果值
|
||||
EffectRound []int `json:"effect_round"` //效果持续回合数
|
||||
}
|
||||
|
||||
type Conf struct {
|
||||
CfgId int `json:"cfgId"`
|
||||
Name string `json:"name"`
|
||||
Trigger int `json:"trigger"` //发起类型
|
||||
Target int `json:"target"` //目标类型
|
||||
Des string `json:"des"`
|
||||
Limit int `json:"limit"` //可以被武将装备上限
|
||||
Arms []int `json:"arms"` //可以装备的兵种
|
||||
IncludeEffect []int `json:"include_effect"` //技能包括的效果
|
||||
Levels []level `json:"levels"`
|
||||
}
|
||||
39
server/slgserver/static_conf/skill/skill_outline.go
Normal file
39
server/slgserver/static_conf/skill/skill_outline.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package skill
|
||||
|
||||
type trigger struct {
|
||||
Type int `json:"type"`
|
||||
Des string `json:"des"`
|
||||
}
|
||||
|
||||
type triggerType struct {
|
||||
Des string `json:"des"`
|
||||
List [] trigger `json:"list"`
|
||||
}
|
||||
|
||||
type effect struct {
|
||||
Type int `json:"type"`
|
||||
Des string `json:"des"`
|
||||
IsRate bool `json:"isRate"`
|
||||
}
|
||||
|
||||
type effectType struct {
|
||||
Des string `json:"des"`
|
||||
List [] effect `json:"list"`
|
||||
}
|
||||
|
||||
type target struct {
|
||||
Type int `json:"type"`
|
||||
Des string `json:"des"`
|
||||
}
|
||||
|
||||
type targetType struct {
|
||||
Des string `json:"des"`
|
||||
List [] target `json:"list"`
|
||||
}
|
||||
|
||||
|
||||
type outline struct {
|
||||
TriggerType triggerType `json:"trigger_type"` //触发类型
|
||||
EffectType effectType `json:"effect_type"` //效果类型
|
||||
TargetType targetType `json:"target_type"` //目标类型
|
||||
}
|
||||
Reference in New Issue
Block a user