first commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
bin/
|
||||
233
config/config.go
Normal file
233
config/config.go
Normal file
@@ -0,0 +1,233 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
V *viper.Viper
|
||||
ROOT string
|
||||
)
|
||||
|
||||
const mainIniPath = "bin/conf/env.ini"
|
||||
|
||||
func init() {
|
||||
root, err := findConfigRoot()
|
||||
if err != nil {
|
||||
slog.Warn("can't find config root", "error", err)
|
||||
ROOT, _ = os.Getwd()
|
||||
} else {
|
||||
ROOT = root
|
||||
}
|
||||
|
||||
configPath := filepath.Join(ROOT, mainIniPath)
|
||||
|
||||
V = viper.New()
|
||||
|
||||
// 使用 ini 包解析配置文件
|
||||
cfg, err := ini.Load(configPath)
|
||||
if err != nil {
|
||||
slog.Error("load config file error", "error", err)
|
||||
// 创建一个空的配置
|
||||
cfg = ini.Empty()
|
||||
}
|
||||
|
||||
// 将 ini 配置加载到 viper 中
|
||||
loadIniToViper(cfg, V)
|
||||
|
||||
if err = loadIncludeFiles(); err != nil {
|
||||
panic("load include files error:" + err.Error())
|
||||
}
|
||||
|
||||
go signalReload()
|
||||
}
|
||||
|
||||
func ReloadConfigFile() {
|
||||
configPath := filepath.Join(ROOT, mainIniPath)
|
||||
|
||||
// 使用 ini 包重新加载配置文件
|
||||
cfg, err := ini.Load(configPath)
|
||||
if err != nil {
|
||||
slog.Error("reload config file error", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 清空现有配置并重新加载
|
||||
V = viper.New()
|
||||
loadIniToViper(cfg, V)
|
||||
|
||||
if err := loadIncludeFiles(); err != nil {
|
||||
slog.Error("reload include files error", "error", err)
|
||||
return
|
||||
}
|
||||
slog.Info("reload config file successfully")
|
||||
}
|
||||
|
||||
func SaveConfigFile() error {
|
||||
configPath := filepath.Join(ROOT, mainIniPath)
|
||||
if err := V.WriteConfigAs(configPath); err != nil {
|
||||
slog.Error("save config file error", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
slog.Info("save config file successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadIncludeFiles() error {
|
||||
includeFile := GetString("include_files.path", "")
|
||||
if includeFile != "" {
|
||||
includeFiles := strings.Split(includeFile, ",")
|
||||
for _, file := range includeFiles {
|
||||
file = strings.TrimSpace(file)
|
||||
if file != "" {
|
||||
// 使用绝对路径或相对路径
|
||||
if !filepath.IsAbs(file) {
|
||||
file = filepath.Join(ROOT, file)
|
||||
}
|
||||
// 使用 ini 包加载包含的配置文件
|
||||
cfg, err := ini.Load(file)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read config file %s: %w", file, err)
|
||||
}
|
||||
// 合并配置到主 viper 实例
|
||||
loadIniToViper(cfg, V)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetString 获取字符串配置值,支持 section.key 格式
|
||||
func GetString(key string, defaultValue string) string {
|
||||
if V.IsSet(key) {
|
||||
return V.GetString(key)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetInt 获取整数配置值,支持 section.key 格式
|
||||
func GetInt(key string, defaultValue int) int {
|
||||
if V.IsSet(key) {
|
||||
return V.GetInt(key)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetBool 获取布尔配置值,支持 section.key 格式
|
||||
func GetBool(key string, defaultValue bool) bool {
|
||||
if V.IsSet(key) {
|
||||
return V.GetBool(key)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetSection 获取整个 section 的配置,返回 map[string]string
|
||||
func GetSection(section string) (map[string]string, error) {
|
||||
// 从 viper 中获取 section,格式为 section.key
|
||||
sectionMap := make(map[string]string)
|
||||
|
||||
// 遍历所有配置键,查找属于该 section 的配置
|
||||
allKeys := V.AllKeys()
|
||||
found := false
|
||||
for _, key := range allKeys {
|
||||
if strings.HasPrefix(key, section+".") {
|
||||
found = true
|
||||
subKey := strings.TrimPrefix(key, section+".")
|
||||
sectionMap[subKey] = V.GetString(key)
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, fmt.Errorf("section %s not found", section)
|
||||
}
|
||||
return sectionMap, nil
|
||||
}
|
||||
|
||||
// GetPath 获取路径配置值,如果是相对路径则基于 ROOT 解析为绝对路径
|
||||
func GetPath(key string, defaultValue string) string {
|
||||
pathValue := GetString(key, defaultValue)
|
||||
if pathValue == "" {
|
||||
return defaultValue
|
||||
}
|
||||
// 如果是绝对路径,直接返回
|
||||
if filepath.IsAbs(pathValue) {
|
||||
return pathValue
|
||||
}
|
||||
// 相对路径基于 ROOT 解析
|
||||
return filepath.Join(ROOT, pathValue)
|
||||
}
|
||||
|
||||
// loadIniToViper 将 ini 配置加载到 viper 中
|
||||
func loadIniToViper(cfg *ini.File, v *viper.Viper) {
|
||||
for _, section := range cfg.Sections() {
|
||||
sectionName := section.Name()
|
||||
// 跳过默认 section (DEFAULT)
|
||||
if sectionName == ini.DEFAULT_SECTION {
|
||||
sectionName = ""
|
||||
}
|
||||
|
||||
for _, key := range section.Keys() {
|
||||
keyName := key.Name()
|
||||
value := key.Value()
|
||||
|
||||
// 构建 viper 键名:section.key 或 key (如果 section 为空)
|
||||
var viperKey string
|
||||
if sectionName != "" {
|
||||
viperKey = sectionName + "." + keyName
|
||||
} else {
|
||||
viperKey = keyName
|
||||
}
|
||||
|
||||
v.Set(viperKey, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fileExist 检查文件或目录是否存在
|
||||
// 如果由 filename 指定的文件或目录存在则返回 true,否则返回 false
|
||||
func fileExist(filename string) bool {
|
||||
_, err := os.Stat(filename)
|
||||
return err == nil || os.IsExist(err)
|
||||
}
|
||||
|
||||
func findConfigRoot() (string, error) {
|
||||
if execPath, err := os.Executable(); err == nil {
|
||||
if root := searchConfig(filepath.Dir(execPath)); root != "" {
|
||||
return root, nil
|
||||
}
|
||||
}
|
||||
|
||||
if wd, err := os.Getwd(); err == nil {
|
||||
if root := searchConfig(wd); root != "" {
|
||||
return root, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("unable to locate %s", mainIniPath)
|
||||
}
|
||||
|
||||
func searchConfig(start string) string {
|
||||
dir := start
|
||||
for {
|
||||
configPath := filepath.Join(dir, mainIniPath)
|
||||
if fileExist(configPath) {
|
||||
return dir
|
||||
}
|
||||
|
||||
parent := filepath.Dir(dir)
|
||||
if parent == dir {
|
||||
break
|
||||
}
|
||||
dir = parent
|
||||
}
|
||||
return ""
|
||||
}
|
||||
22
config/reload_unix.go
Normal file
22
config/reload_unix.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// +build !windows,!plan9
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func signalReload() {
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGUSR1)
|
||||
|
||||
for {
|
||||
sig := <-ch
|
||||
switch sig {
|
||||
case syscall.SIGUSR1:
|
||||
ReloadConfigFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
4
config/reload_windows.go
Normal file
4
config/reload_windows.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package config
|
||||
|
||||
func signalReload() {
|
||||
}
|
||||
73
constant/code.go
Normal file
73
constant/code.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package constant
|
||||
|
||||
const ProxyConnectError = -4 //代理连接失败
|
||||
const ProxyNotInConnect = -3 //代理错误
|
||||
const UserNotInConnect = -2 //链接没有找到用户
|
||||
const RoleNotInConnect = -1 //链接没有找到角色
|
||||
const OK = 0
|
||||
const InvalidParam = 1 //参数有误
|
||||
const DBError = 2 //数据库异常
|
||||
const UserExist = 3 //用户已存在
|
||||
const PwdIncorrect = 4 //密码不正确
|
||||
const UserNotExist = 5 //用户不存在
|
||||
const SessionInvalid = 6 //session无效
|
||||
const HardwareIncorrect = 7 //Hardware错误
|
||||
const RoleAlreadyCreate = 8 //已经创建过角色了
|
||||
const RoleNotExist = 9 //角色不存在
|
||||
const CityNotExist = 10 //城市不存在
|
||||
const CityNotMe = 11 //城市不是自己的
|
||||
const UpError = 12 //升级失败
|
||||
const GeneralNotFound = 13 //武将不存在
|
||||
const GeneralNotMe = 14 //武将不是自己的
|
||||
const ArmyNotFound = 15 //军队不存在
|
||||
const ArmyNotMe = 16 //军队不是自己的
|
||||
const ResNotEnough = 17 //资源不足
|
||||
const OutArmyLimit = 18 //超过带兵限制
|
||||
const ArmyBusy = 19 //军队再忙
|
||||
const GeneralBusy = 20 //将领再忙
|
||||
const CannotGiveUp = 21 //不能放弃
|
||||
const BuildNotMe = 22 //领地不是自己的
|
||||
const ArmyNotMain = 23 //军队没有主将
|
||||
const UnReachable = 24 //不可到达
|
||||
const PhysicalPowerNotEnough = 25 //体力不足
|
||||
const DecreeNotEnough = 26 //政令不足
|
||||
const GoldNotEnough = 27 //金币不足
|
||||
const GeneralRepeat = 28 //重复上阵
|
||||
const CostNotEnough = 29 //cost不足
|
||||
const GeneralNoHas = 30 //没有该合成武将
|
||||
const GeneralNoSame = 31 //合成武将非同名
|
||||
const ArmyNotEnough = 32 //队伍数不足
|
||||
const TongShuaiNotEnough = 33 //统帅不足
|
||||
const GeneralStarMax = 34 //升级到最大星级
|
||||
const UnionCreateError = 35 //联盟创建失败
|
||||
const UnionNotFound = 36 //联盟不存在
|
||||
const PermissionDenied = 37 //权限不足
|
||||
const UnionAlreadyHas = 38 //已经有联盟
|
||||
const UnionNotAllowExit = 39 //不允许退出
|
||||
const ContentTooLong = 40 //内容太长
|
||||
const NotBelongUnion = 41 //不属于该联盟
|
||||
const PeopleIsFull = 42 //用户已满
|
||||
const HasApply = 43 //已经申请过了
|
||||
const BuildCanNotDefend = 44 //不能驻守
|
||||
const BuildCanNotAttack = 45 //不能占领
|
||||
const BuildMBSNotFound = 46 //没有军营
|
||||
const BuildWarFree = 47 //免战中
|
||||
const ArmyConscript = 48 //征兵中
|
||||
const BuildGiveUpAlready = 49 //领地已经在放弃了
|
||||
const CanNotBuildNew = 50 //不能再新建建筑在领地上
|
||||
const CanNotTransfer = 51 //不能调兵
|
||||
const HoldIsFull = 52 //坑位已满
|
||||
const ArmyIsOutside = 53 //队伍在城外
|
||||
const CanNotUpBuild = 54 //不能升级建筑
|
||||
const CanNotDestroy = 55 //不能拆除建筑
|
||||
const OutCollectTimesLimit = 56 //超过征收次数
|
||||
const InCdCanNotOperate = 57 //cd内不能操作
|
||||
const OutGeneralLimit = 58 //武将超过上限了
|
||||
const NotHasJiShi = 59 //没有集市
|
||||
const OutPosTagLimit = 60 //超过了收藏上限
|
||||
const OutSkillLimit = 61 //超过了技能上限
|
||||
const UpSkillError = 62 //装备技能失败
|
||||
const DownSkillError = 63 //取下技能失败
|
||||
const OutArmNotMatch = 64 //兵种不符
|
||||
const PosNotSkill = 65 //该位置没有技能
|
||||
const SkillLevelFull = 66 //技能等级已满
|
||||
233
data/conf/db.sql
Normal file
233
data/conf/db.sql
Normal file
@@ -0,0 +1,233 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_user_info` (
|
||||
`uid` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(20) NOT NULL COMMENT '用户名',
|
||||
`passcode` char(12) NOT NULL DEFAULT '' COMMENT '加密随机数',
|
||||
`passwd` char(64) NOT NULL DEFAULT '' COMMENT 'md5密码',
|
||||
`status` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '用户账号状态。0-默认;1-冻结;2-停号',
|
||||
`hardware` varchar(64) NOT NULL DEFAULT '' COMMENT 'hardware',
|
||||
`ctime` timestamp NOT NULL DEFAULT '2013-03-15 14:38:09',
|
||||
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`uid`),
|
||||
UNIQUE KEY (`username`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '用户信息表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_login_history` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uid` int unsigned NOT NULL DEFAULT 0 COMMENT '用户UID',
|
||||
`state` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '登录状态,0登录,1登出',
|
||||
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '登录时间',
|
||||
`ip` varchar(31) NOT NULL DEFAULT '' COMMENT 'ip',
|
||||
`hardware` varchar(64) NOT NULL DEFAULT '' COMMENT 'hardware',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '用户登录表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_login_last` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uid` int unsigned NOT NULL DEFAULT 0 COMMENT '用户UID',
|
||||
`login_time` timestamp COMMENT '登录时间',
|
||||
`logout_time` timestamp COMMENT '登出时间',
|
||||
`ip` varchar(31) NOT NULL DEFAULT '' COMMENT 'ip',
|
||||
`is_logout` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '是否logout,1:logout,0:login',
|
||||
`session` varchar(100) COMMENT '会话',
|
||||
`hardware` varchar(64) NOT NULL DEFAULT '' COMMENT 'hardware',
|
||||
UNIQUE KEY (`uid`),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '最后一次用户登录表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_role_1` (
|
||||
`rid` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'roleId',
|
||||
`uid` int unsigned NOT NULL COMMENT '用户UID',
|
||||
`headId` int unsigned NOT NULL DEFAULT 0 COMMENT '头像Id',
|
||||
`sex` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '性别,0:女 1男',
|
||||
`nick_name` varchar(100) COMMENT 'nick_name',
|
||||
`balance` int unsigned NOT NULL DEFAULT 0 COMMENT '余额',
|
||||
`login_time` timestamp COMMENT '登录时间',
|
||||
`logout_time` timestamp COMMENT '登出时间',
|
||||
`profile` varchar(500) COMMENT '个人简介',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY (`uid`),
|
||||
PRIMARY KEY (`rid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '玩家表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_map_role_city_1` (
|
||||
`cityId` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'cityId',
|
||||
`rid` int unsigned NOT NULL COMMENT 'roleId',
|
||||
`x` int unsigned NOT NULL COMMENT 'x坐标',
|
||||
`y` int unsigned NOT NULL COMMENT 'y坐标',
|
||||
`name` varchar(100) NOT NULL DEFAULT '城池' COMMENT '城池名称',
|
||||
`is_main` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '是否是主城',
|
||||
`cur_durable` int unsigned NOT NULL COMMENT '当前耐久',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`occupy_time` timestamp DEFAULT '2013-03-15 14:38:09' COMMENT '占领时间',
|
||||
PRIMARY KEY (`cityId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '玩家城池';
|
||||
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_map_role_build_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`rid` int unsigned NOT NULL,
|
||||
`type` int unsigned NOT NULL COMMENT '建筑类型',
|
||||
`level` tinyint unsigned NOT NULL COMMENT '建筑等级',
|
||||
`op_level` tinyint unsigned COMMENT '建筑操作等级',
|
||||
`x` int unsigned NOT NULL COMMENT 'x坐标',
|
||||
`y` int unsigned NOT NULL COMMENT 'y坐标',
|
||||
`name` varchar(100) NOT NULL COMMENT '名称',
|
||||
`max_durable` int unsigned NOT NULL COMMENT '最大耐久',
|
||||
`cur_durable` int unsigned NOT NULL COMMENT '当前耐久',
|
||||
`end_time` timestamp DEFAULT '2013-03-15 14:38:09' COMMENT '建造、升级、拆除结束时间',
|
||||
`occupy_time` timestamp DEFAULT '2013-03-15 14:38:09' COMMENT '占领时间',
|
||||
`giveUp_time` int unsigned DEFAULT '0' COMMENT '放弃时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '角色建筑';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_city_facility_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`cityId` int unsigned NOT NULL COMMENT '城市id',
|
||||
`rid` int unsigned NOT NULL,
|
||||
`facilities` varchar(4096) NOT NULL COMMENT '设施列表,格式为json结构',
|
||||
UNIQUE KEY (`cityId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '城池设施';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_role_res_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`rid` int unsigned NOT NULL COMMENT 'rid',
|
||||
`wood` int unsigned NOT NULL COMMENT '木',
|
||||
`iron` int unsigned NOT NULL COMMENT '铁',
|
||||
`stone` int unsigned NOT NULL COMMENT '石头',
|
||||
`grain` int unsigned NOT NULL COMMENT '粮食',
|
||||
`gold` int unsigned NOT NULL COMMENT '金币',
|
||||
`decree` int unsigned NOT NULL COMMENT '令牌',
|
||||
UNIQUE KEY (`rid`),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '角色资源表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_general_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`rid` int unsigned NOT NULL COMMENT 'rid',
|
||||
`cfgId` int unsigned NOT NULL COMMENT '配置id',
|
||||
`physical_power` int unsigned NOT NULL COMMENT '体力',
|
||||
`exp` int unsigned NOT NULL COMMENT '经验',
|
||||
`order` tinyint NOT NULL COMMENT '第几队',
|
||||
`level` tinyint unsigned NOT NULL DEFAULT 1 COMMENT 'level',
|
||||
`cityId` int NOT NULL DEFAULT 0 COMMENT '城市id',
|
||||
`star` int NOT NULL DEFAULT 0 COMMENT '稀有度(星级)',
|
||||
`star_lv` int NOT NULL DEFAULT 0 COMMENT '稀有度(星级)进阶等级级',
|
||||
`arms` int NOT NULL DEFAULT 0 COMMENT '兵种',
|
||||
`has_pr_point` int NOT NULL DEFAULT 0 COMMENT '总属性点',
|
||||
`use_pr_point` int NOT NULL DEFAULT 0 COMMENT '已用属性点',
|
||||
`attack_distance` int NOT NULL DEFAULT 0 COMMENT '攻击距离',
|
||||
`force_added` int NOT NULL DEFAULT 0 COMMENT '已加攻击属性',
|
||||
`strategy_added` int NOT NULL DEFAULT 0 COMMENT '已加战略属性',
|
||||
`defense_added` int NOT NULL DEFAULT 0 COMMENT '已加防御属性',
|
||||
`speed_added` int NOT NULL DEFAULT 0 COMMENT '已加速度属性',
|
||||
`destroy_added` int NOT NULL DEFAULT 0 COMMENT '已加破坏属性',
|
||||
`parentId` int NOT NULL DEFAULT 0 COMMENT '已合成到武将的id',
|
||||
`compose_type` int NOT NULL DEFAULT 0 COMMENT '合成类型',
|
||||
`skills` varchar(64) NOT NULL DEFAULT '[0, 0, 0]' COMMENT '携带的技能',
|
||||
`state` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '0:正常,1:转换掉了',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '将领表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_army_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`rid` int unsigned NOT NULL COMMENT 'rid',
|
||||
`cityId` int unsigned NOT NULL COMMENT '城市id',
|
||||
`order` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '第几队 1-5队',
|
||||
`generals` varchar(256) NOT NULL DEFAULT '[0, 0, 0]' COMMENT '将领',
|
||||
`soldiers` varchar(256) NOT NULL DEFAULT '[0, 0, 0]' COMMENT '士兵',
|
||||
`conscript_times` varchar(256) NOT NULL DEFAULT '[0, 0, 0]' COMMENT '征兵结束时间',
|
||||
`conscript_cnts` varchar(256) NOT NULL DEFAULT '[0, 0, 0]' COMMENT '征兵数量',
|
||||
`cmd` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '命令 0:空闲 1:攻击 2:驻军 3:返回',
|
||||
`from_x` int unsigned NOT NULL COMMENT '来自x坐标',
|
||||
`from_y` int unsigned NOT NULL COMMENT '来自y坐标',
|
||||
`to_x` int unsigned COMMENT '去往x坐标',
|
||||
`to_y` int unsigned COMMENT '去往y坐标',
|
||||
`start` timestamp COMMENT '出发时间',
|
||||
`end` timestamp COMMENT '到达时间',
|
||||
UNIQUE KEY (`rid`, `cityId`, `order`),
|
||||
PRIMARY KEY (`id`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '军队表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_war_report_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`a_rid` int unsigned NOT NULL COMMENT '攻击方id',
|
||||
`d_rid` int unsigned NOT NULL DEFAULT 0 COMMENT '防守方id,0为系统npc',
|
||||
`b_a_army` varchar(512) NOT NULL COMMENT '开始攻击方军队',
|
||||
`b_d_army` varchar(512) NOT NULL COMMENT '开始防守方军队',
|
||||
`e_a_army` varchar(512) NOT NULL COMMENT '开始攻击方军队',
|
||||
`e_d_army` varchar(512) NOT NULL COMMENT '开始防守方军队',
|
||||
`b_a_general` varchar(512) NOT NULL COMMENT '开始攻击方武将',
|
||||
`b_d_general` varchar(512) NOT NULL COMMENT '开始防守方武将',
|
||||
`e_a_general` varchar(512) NOT NULL COMMENT '结束攻击方武将',
|
||||
`e_d_general` varchar(512) NOT NULL COMMENT '结束防守方武将',
|
||||
`rounds` varchar(1024) NOT NULL COMMENT '回合战报数据',
|
||||
`result` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '0失败,1打平,2胜利',
|
||||
`a_is_read` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '攻击方战报是否已阅 0:未阅 1:已阅',
|
||||
`d_is_read` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '攻击方战报是否已阅 0:未阅 1:已阅',
|
||||
`destroy` int unsigned COMMENT '破坏了多少耐久',
|
||||
`occupy` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '是否攻占 0:否 1:是',
|
||||
`x` int unsigned COMMENT 'x坐标',
|
||||
`y` int unsigned COMMENT 'y坐标',
|
||||
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '战报表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_coalition_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`name` varchar(20) NOT NULL COMMENT '联盟名字',
|
||||
`members` varchar(2048) NOT NULL COMMENT '成员',
|
||||
`create_id` int unsigned NOT NULL COMMENT '创建者id',
|
||||
`chairman` int unsigned NOT NULL COMMENT '盟主',
|
||||
`vice_chairman` int unsigned NOT NULL COMMENT '副盟主',
|
||||
`notice` varchar(256) COMMENT '公告',
|
||||
`state` tinyint unsigned NOT NULL DEFAULT '1' COMMENT '0解散,1运行中',
|
||||
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY (`name`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '联盟';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_coalition_apply_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`union_id` int unsigned NOT NULL COMMENT '联盟id',
|
||||
`rid` int unsigned NOT NULL COMMENT '申请者的rid',
|
||||
`state` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '申请状态,0未处理,1拒绝,2通过',
|
||||
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '联盟申请表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_role_attribute_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`rid` int unsigned NOT NULL COMMENT 'rid',
|
||||
`parent_id` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '上级联盟id',
|
||||
`collect_times` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '征收次数',
|
||||
`last_collect_time` timestamp DEFAULT '2013-03-15 14:38:09' COMMENT '最后征收时间',
|
||||
`pos_tags` varchar(512) COMMENT '收藏的位置',
|
||||
PRIMARY KEY (`id`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '玩家属性表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_coalition_log_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`union_id` int unsigned NOT NULL COMMENT '联盟id',
|
||||
`op_rid` int unsigned NOT NULL COMMENT '操作者id',
|
||||
`target_id` int unsigned COMMENT '被操作的对象',
|
||||
`des` varchar(256) NOT NULL COMMENT '描述',
|
||||
`state` tinyint unsigned NOT NULL COMMENT '0:创建,1:解散,2:加入,3:退出,4:踢出,5:任命,6:禅让,7:修改公告',
|
||||
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '发生时间',
|
||||
PRIMARY KEY (`id`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '联盟日志表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `tb_skill_1` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`rid` int unsigned NOT NULL COMMENT 'rid',
|
||||
`cfgId` int unsigned NOT NULL COMMENT '技能id',
|
||||
`belong_generals` varchar(256) NOT NULL Default '[]' COMMENT '归属武将数组',
|
||||
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '获得技能时间',
|
||||
PRIMARY KEY (`id`)
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '技能表';
|
||||
|
||||
|
||||
|
||||
56
data/conf/env.ini
Normal file
56
data/conf/env.ini
Normal file
@@ -0,0 +1,56 @@
|
||||
[mysql]
|
||||
host = 127.0.0.1
|
||||
port = 3306
|
||||
user = root
|
||||
password = root
|
||||
dbname = slgdb
|
||||
charset = utf8
|
||||
; 最大空闲连接数
|
||||
max_idle = 2
|
||||
; 最大打开连接数
|
||||
max_conn = 10
|
||||
|
||||
[httpserver]
|
||||
host =
|
||||
port = 8088
|
||||
|
||||
|
||||
[gateserver]
|
||||
host =
|
||||
port = 8004
|
||||
need_secret = true
|
||||
slg_proxy = ws://127.0.0.1:8001
|
||||
chat_proxy = ws://127.0.0.1:8002
|
||||
login_proxy = ws://127.0.0.1:8003
|
||||
|
||||
[slgserver]
|
||||
host =
|
||||
port = 8001
|
||||
need_secret = false
|
||||
|
||||
[chatserver]
|
||||
host =
|
||||
port = 8002
|
||||
need_secret = false
|
||||
|
||||
[loginserver]
|
||||
host =
|
||||
port = 8003
|
||||
need_secret = false
|
||||
|
||||
|
||||
[xorm]
|
||||
show_sql = true
|
||||
log_file = ../logs/sql.log
|
||||
|
||||
[log]
|
||||
file_dir = ../logs/
|
||||
max_size = 120
|
||||
max_backups = 100
|
||||
max_age = 10
|
||||
compress = true
|
||||
|
||||
[logic]
|
||||
map_data = data/conf/mapRes_0.json
|
||||
json_data = data/conf/json/
|
||||
server_id = 1
|
||||
96
data/conf/json/basic.json
Normal file
96
data/conf/json/basic.json
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"conscript": {
|
||||
"des": "每征一个兵需要消耗的资源",
|
||||
"cost_wood":10,
|
||||
"cost_iron":10,
|
||||
"cost_stone":0,
|
||||
"cost_grain":10,
|
||||
"cost_gold":1,
|
||||
"cost_time":1
|
||||
},
|
||||
"general": {
|
||||
"des": "武将的一些配置",
|
||||
"physical_power_limit": 100,
|
||||
"cost_physical_power": 1,
|
||||
"recovery_physical_power": 10,
|
||||
"reclamation_time": 30,
|
||||
"reclamation_cost": 1,
|
||||
"draw_general_cost": 30,
|
||||
"pr_point": 1000,
|
||||
"limit": 500
|
||||
},
|
||||
"role": {
|
||||
"des": "角色的一些配置",
|
||||
"wood": 1000000,
|
||||
"iron": 1000000,
|
||||
"stone": 1000000,
|
||||
"grain": 1000000,
|
||||
"gold": 1000000,
|
||||
"decree": 20,
|
||||
"wood_yield": 1000000,
|
||||
"iron_yield": 1000000,
|
||||
"stone_yield": 1000000,
|
||||
"grain_yield": 1000000,
|
||||
"gold_yield": 1000000,
|
||||
"depot_capacity": 100000000000,
|
||||
"build_limit": 20,
|
||||
"recovery_time": 20,
|
||||
"decree_limit": 20,
|
||||
"collect_times_limit": 3,
|
||||
"collect_interval": 30,
|
||||
"pos_tag_limit": 10
|
||||
},
|
||||
"city": {
|
||||
"des": "城池的一些配置",
|
||||
"cost": 75,
|
||||
"durable": 100000,
|
||||
"transform_rate": 50,
|
||||
"recovery_time": 600
|
||||
},
|
||||
"build": {
|
||||
"des": "建筑的一些配置",
|
||||
"war_free": 20,
|
||||
"giveUp_time": 30,
|
||||
"fortress_limit": 10
|
||||
},
|
||||
"npc": {
|
||||
"des": "npc一些配置",
|
||||
"levels": [
|
||||
{
|
||||
"soilders": 100
|
||||
},
|
||||
{
|
||||
"soilders": 200
|
||||
},
|
||||
{
|
||||
"soilders": 300
|
||||
},
|
||||
{
|
||||
"soilders": 400
|
||||
},
|
||||
{
|
||||
"soilders": 500
|
||||
},
|
||||
{
|
||||
"soilders": 600
|
||||
},
|
||||
{
|
||||
"soilders": 700
|
||||
},
|
||||
{
|
||||
"soilders": 800
|
||||
},
|
||||
{
|
||||
"soilders": 900
|
||||
},
|
||||
{
|
||||
"soilders": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
"union": {
|
||||
"des": "联盟的一些配置",
|
||||
"member_limit": 100
|
||||
}
|
||||
|
||||
}
|
||||
109
data/conf/json/facility/facility.json
Normal file
109
data/conf/json/facility/facility.json
Normal file
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"title": "城内设施类型",
|
||||
"list": [
|
||||
{
|
||||
"type": 0,
|
||||
"name": "主城"
|
||||
},
|
||||
{
|
||||
"type": 1,
|
||||
"name": "疾风营"
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"name": "铁壁营"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"name": "军机营"
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"name": "尚武营"
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"name": "军营"
|
||||
},
|
||||
{
|
||||
"type": 6,
|
||||
"name": "预备役所"
|
||||
},
|
||||
{
|
||||
"type": 7,
|
||||
"name": "汉点将台"
|
||||
},
|
||||
{
|
||||
"type": 8,
|
||||
"name": "魏点将台"
|
||||
},
|
||||
{
|
||||
"type": 9,
|
||||
"name": "蜀点将台"
|
||||
},
|
||||
{
|
||||
"type": 10,
|
||||
"name": "吴点将台"
|
||||
},
|
||||
{
|
||||
"type": 11,
|
||||
"name": "群点将台"
|
||||
},
|
||||
{
|
||||
"type": 12,
|
||||
"name": "封禅台"
|
||||
},
|
||||
{
|
||||
"type": 13,
|
||||
"name": "校场"
|
||||
},
|
||||
{
|
||||
"type": 14,
|
||||
"name": "统帅厅"
|
||||
},
|
||||
{
|
||||
"type": 15,
|
||||
"name": "集市"
|
||||
},
|
||||
{
|
||||
"type": 16,
|
||||
"name": "募兵所"
|
||||
},
|
||||
{
|
||||
"type": 17,
|
||||
"name": "伐木场"
|
||||
},
|
||||
{
|
||||
"type": 18,
|
||||
"name": "炼铁场"
|
||||
},
|
||||
{
|
||||
"type": 19,
|
||||
"name": "磨坊"
|
||||
},
|
||||
{
|
||||
"type": 20,
|
||||
"name": "采石场"
|
||||
},
|
||||
{
|
||||
"type": 21,
|
||||
"name": "民居"
|
||||
},
|
||||
{
|
||||
"type": 22,
|
||||
"name": "社稷坛"
|
||||
},
|
||||
{
|
||||
"type": 23,
|
||||
"name": "城墙"
|
||||
},
|
||||
{
|
||||
"type": 24,
|
||||
"name": "女墙"
|
||||
},
|
||||
{
|
||||
"type": 25,
|
||||
"name": "仓库"
|
||||
}
|
||||
]
|
||||
}
|
||||
131
data/conf/json/facility/facility_addition.json
Normal file
131
data/conf/json/facility/facility_addition.json
Normal file
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"title": "城池设施加成类别",
|
||||
"list": [
|
||||
{
|
||||
"type": 1,
|
||||
"des": "耐久度上限",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"des": "部队统帅上限",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"des": "可配置队伍数",
|
||||
"value": "%n%"
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"des": "部队速度",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"des": "部队防御",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 6,
|
||||
"des": "部队谋略",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 7,
|
||||
"des": "部队攻击",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 8,
|
||||
"des": "征兵时间",
|
||||
"value": "-%n%%"
|
||||
},
|
||||
{
|
||||
"type": 9,
|
||||
"des": "预备役上限",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 10,
|
||||
"des": "金币",
|
||||
"value": "-%n%%"
|
||||
},
|
||||
{
|
||||
"type": 11,
|
||||
"des": "汉阵营加成",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 12,
|
||||
"des": "群阵营加成",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 13,
|
||||
"des": "魏阵营加成",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 14,
|
||||
"des": "蜀阵营加成",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 15,
|
||||
"des": "吴阵营加成",
|
||||
"value": "+%n%"
|
||||
},
|
||||
|
||||
{
|
||||
"type": 16,
|
||||
"des": "交易兑换率",
|
||||
"value": "+%n%%"
|
||||
},
|
||||
{
|
||||
"type": 17,
|
||||
"des": "木材产量",
|
||||
"value": "+%n%/小时"
|
||||
},
|
||||
{
|
||||
"type": 18,
|
||||
"des": "铁矿产量",
|
||||
"value": "+%n%/小时"
|
||||
},
|
||||
{
|
||||
"type": 19,
|
||||
"des": "粮食产量",
|
||||
"value": "+%n%/小时"
|
||||
},
|
||||
{
|
||||
"type": 20,
|
||||
"des": "石矿产量",
|
||||
"value": "+%n%/小时"
|
||||
},
|
||||
{
|
||||
"type": 21,
|
||||
"des": "税收",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 22,
|
||||
"des": "扩建次数",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 23,
|
||||
"des": "仓库容量",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 24,
|
||||
"des": "带兵数量",
|
||||
"value": "+%n%"
|
||||
},
|
||||
{
|
||||
"type": 25,
|
||||
"des": "可配置前锋部队数量",
|
||||
"value": "%n%"
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_army_jfy.json
Normal file
87
data/conf/json/facility/facility_army_jfy.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-疾风营配置表",
|
||||
"name": "疾风营",
|
||||
"type": 1,
|
||||
"des": "提高本城部队速度",
|
||||
"additions": [
|
||||
4
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_army_jjy.json
Normal file
87
data/conf/json/facility/facility_army_jjy.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-军机营配置表",
|
||||
"name": "军机营",
|
||||
"type": 3,
|
||||
"des": "提高本城部队谋略",
|
||||
"additions": [
|
||||
6
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 3
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_army_swy.json
Normal file
87
data/conf/json/facility/facility_army_swy.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-尚武营配置表",
|
||||
"name": "尚武营",
|
||||
"type": 4,
|
||||
"des": "提高本城部队攻击",
|
||||
"additions": [
|
||||
7
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 3
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_army_tby.json
Normal file
87
data/conf/json/facility/facility_army_tby.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-铁壁营配置表",
|
||||
"name": "铁壁营",
|
||||
"type": 2,
|
||||
"des": "提高本城部队防御",
|
||||
"additions": [
|
||||
5
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_barrack_by.json
Normal file
87
data/conf/json/facility/facility_barrack_by.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-兵营配置表",
|
||||
"name": "兵营",
|
||||
"type": 5,
|
||||
"des": "提高本城部队武将带兵数量",
|
||||
"additions": [
|
||||
24
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 7
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
100
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
200
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
300
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
400
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
500
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
91
data/conf/json/facility/facility_barrack_yby.json
Normal file
91
data/conf/json/facility/facility_barrack_yby.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"title": "城内设施-预备役配置表",
|
||||
"name": "预备役所",
|
||||
"type": 6,
|
||||
"des": "提高本城预备役上限",
|
||||
"additions": [
|
||||
9
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 6
|
||||
},
|
||||
{
|
||||
"type": 13,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_camp_han.json
Normal file
87
data/conf/json/facility/facility_camp_han.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-汉点将台配置表",
|
||||
"name": "汉点将台",
|
||||
"type": 7,
|
||||
"des": "提高汉阵营加成效果",
|
||||
"additions": [
|
||||
11
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 4
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
99
data/conf/json/facility/facility_camp_qun.json
Normal file
99
data/conf/json/facility/facility_camp_qun.json
Normal file
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"title": "城内设施-群点将台配置表",
|
||||
"name": "群点将台",
|
||||
"type": 11,
|
||||
"des": "提高群阵营加成效果",
|
||||
"additions": [
|
||||
12
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 6
|
||||
},
|
||||
{
|
||||
"type": 8,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"type": 9,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"type": 10,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
91
data/conf/json/facility/facility_camp_shu.json
Normal file
91
data/conf/json/facility/facility_camp_shu.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"title": "城内设施-蜀点将台配置表",
|
||||
"name": "蜀点将台",
|
||||
"type": 9,
|
||||
"des": "提高蜀阵营加成效果",
|
||||
"additions": [
|
||||
14
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 5
|
||||
},
|
||||
{
|
||||
"type": 7,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
91
data/conf/json/facility/facility_camp_wei.json
Normal file
91
data/conf/json/facility/facility_camp_wei.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"title": "城内设施-魏点将台配置表",
|
||||
"name": "魏点将台",
|
||||
"type": 8,
|
||||
"des": "提高魏阵营加成效果",
|
||||
"additions": [
|
||||
13
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 5
|
||||
},
|
||||
{
|
||||
"type": 7,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
91
data/conf/json/facility/facility_camp_wu.json
Normal file
91
data/conf/json/facility/facility_camp_wu.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"title": "城内设施-吴点将台配置表",
|
||||
"name": "吴点将台",
|
||||
"type": 10,
|
||||
"des": "提高吴阵营加成效果",
|
||||
"additions": [
|
||||
15
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 5
|
||||
},
|
||||
{
|
||||
"type": 7,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
163
data/conf/json/facility/facility_city.json
Normal file
163
data/conf/json/facility/facility_city.json
Normal file
@@ -0,0 +1,163 @@
|
||||
{
|
||||
"title": "主城配置",
|
||||
"name": "主城",
|
||||
"type": 0,
|
||||
"des": "提高本城的耐久上限部队统帅上限",
|
||||
"additions": [
|
||||
1,
|
||||
2
|
||||
],
|
||||
"conditions": [],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
10000,
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
20000,
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
30000,
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
40000,
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
50000,
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
60000,
|
||||
30
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
70000,
|
||||
35
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
80000,
|
||||
40
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
90000,
|
||||
45
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
100000,
|
||||
50
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
91
data/conf/json/facility/facility_fct.json
Normal file
91
data/conf/json/facility/facility_fct.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"title": "城内设施-封禅台配置",
|
||||
"name": "封禅台",
|
||||
"type": 12,
|
||||
"des": "提高本城部队的统帅上限",
|
||||
"additions": [
|
||||
2
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 8
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"level": 5
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_general_jc.json
Normal file
87
data/conf/json/facility/facility_general_jc.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-校场配置表",
|
||||
"name": "校场",
|
||||
"type": 13,
|
||||
"des": "使本城可以配置部队,并提高本城可配置部队数量",
|
||||
"additions": [
|
||||
3
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_general_tst.json
Normal file
87
data/conf/json/facility/facility_general_tst.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-统帅厅配置表",
|
||||
"name": "统帅厅",
|
||||
"type": 14,
|
||||
"des": "使本城可以配置前锋,并提高本城可配置前锋部队数量",
|
||||
"additions": [
|
||||
25
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 16,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
157
data/conf/json/facility/facility_market.json
Normal file
157
data/conf/json/facility/facility_market.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"title": "城内设施-集市配置表",
|
||||
"des": "提高交易兑换率",
|
||||
"name": "集市",
|
||||
"type": 15,
|
||||
"additions": [
|
||||
16
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 5
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
30
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
35
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
40
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
45
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
50
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
160
data/conf/json/facility/facility_mbs.json
Normal file
160
data/conf/json/facility/facility_mbs.json
Normal file
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"title": "募兵所配置表",
|
||||
"des": "开启本城部队征兵,并缩短征兵时间",
|
||||
"name": "募兵所",
|
||||
"type": 16,
|
||||
"additions": [
|
||||
10
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"type": 13,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"levels": [{
|
||||
"level": 1,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
10
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
15
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
20
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
25
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
30
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
35
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
40
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
45
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
50
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
157
data/conf/json/facility/facility_produce_csc.json
Normal file
157
data/conf/json/facility/facility_produce_csc.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"title": "城内设施-采石场配置表",
|
||||
"name": "采石场",
|
||||
"des": "额外获得石矿产量",
|
||||
"type": 20,
|
||||
"additions": [
|
||||
20
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 3
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
6000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
7000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
8000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
9000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
157
data/conf/json/facility/facility_produce_fmc.json
Normal file
157
data/conf/json/facility/facility_produce_fmc.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"title": "城内设施-伐木场配置表",
|
||||
"name": "伐木场",
|
||||
"des": "额外获得木材产量",
|
||||
"type": 17,
|
||||
"additions": [
|
||||
17
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
6000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
7000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
8000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
9000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
157
data/conf/json/facility/facility_produce_ltc.json
Normal file
157
data/conf/json/facility/facility_produce_ltc.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"title": "城内设施-炼铁场配置表",
|
||||
"name": "炼铁场",
|
||||
"des": "额外获得铁矿产量",
|
||||
"type": 18,
|
||||
"additions": [
|
||||
18
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
6000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
7000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
8000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
9000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
157
data/conf/json/facility/facility_produce_mf.json
Normal file
157
data/conf/json/facility/facility_produce_mf.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"title": "城内设施-磨坊配置表",
|
||||
"name": "磨坊",
|
||||
"des": "额外获得粮食产量",
|
||||
"type": 19,
|
||||
"additions": [
|
||||
19
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 3
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
6000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
7000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
8000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
9000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
157
data/conf/json/facility/facility_produce_mj.json
Normal file
157
data/conf/json/facility/facility_produce_mj.json
Normal file
@@ -0,0 +1,157 @@
|
||||
{
|
||||
"title": "城内设施-民居配置表",
|
||||
"name": "民居",
|
||||
"des": "提供税收",
|
||||
"type": 21,
|
||||
"additions": [
|
||||
21
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
6000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
7000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
8000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"values": [
|
||||
9000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 9000,
|
||||
"wood": 9000,
|
||||
"iron": 9000,
|
||||
"stone": 9000
|
||||
},
|
||||
"time": 90
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 10000,
|
||||
"wood": 10000,
|
||||
"iron": 10000,
|
||||
"stone": 10000
|
||||
},
|
||||
"time": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
128
data/conf/json/facility/facility_sjt.json
Normal file
128
data/conf/json/facility/facility_sjt.json
Normal file
@@ -0,0 +1,128 @@
|
||||
{
|
||||
"title": "城内设施-社稷坛配置",
|
||||
"name": "社稷坛",
|
||||
"type": 22,
|
||||
"des": "每升一级可以额外扩建一次",
|
||||
"additions": [
|
||||
22
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 9
|
||||
}
|
||||
],
|
||||
"levels": [{
|
||||
"level": 1,
|
||||
"values": [
|
||||
1
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
2
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
3
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
4
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
5
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
6
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
7
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
8
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_wall_cq.json
Normal file
87
data/conf/json/facility/facility_wall_cq.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-城墙配置",
|
||||
"name": "城墙",
|
||||
"type": 23,
|
||||
"des": "提高本城耐久上限",
|
||||
"additions": [
|
||||
1
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 7
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
20000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
30000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
40000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
50000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
87
data/conf/json/facility/facility_wall_nq.json
Normal file
87
data/conf/json/facility/facility_wall_nq.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"title": "城内设施-女墙配置",
|
||||
"name": "女墙",
|
||||
"type": 24,
|
||||
"des": "提高本城耐久上限",
|
||||
"additions": [
|
||||
1
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 23,
|
||||
"level": 1
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
20000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
30000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
40000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
50000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
129
data/conf/json/facility/facility_warehouse.json
Normal file
129
data/conf/json/facility/facility_warehouse.json
Normal file
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"title": "城内设施-仓库配置",
|
||||
"name": "仓库",
|
||||
"type": 25,
|
||||
"des": "每升一级增加仓库容量",
|
||||
"additions": [
|
||||
23
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"type": 0,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"values": [
|
||||
10000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"time": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"values": [
|
||||
20000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 2000,
|
||||
"wood": 2000,
|
||||
"iron": 2000,
|
||||
"stone": 2000
|
||||
},
|
||||
"time": 20
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"values": [
|
||||
30000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 3000,
|
||||
"wood": 3000,
|
||||
"iron": 3000,
|
||||
"stone": 3000
|
||||
},
|
||||
"time": 30
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"values": [
|
||||
40000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 4000,
|
||||
"wood": 4000,
|
||||
"iron": 4000,
|
||||
"stone": 4000
|
||||
},
|
||||
"time": 40
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"values": [
|
||||
50000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 5000,
|
||||
"wood": 5000,
|
||||
"iron": 5000,
|
||||
"stone": 5000
|
||||
},
|
||||
"time": 50
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"values": [
|
||||
60000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 6000,
|
||||
"wood": 6000,
|
||||
"iron": 6000,
|
||||
"stone": 6000
|
||||
},
|
||||
"time": 60
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"values": [
|
||||
70000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 7000,
|
||||
"wood": 7000,
|
||||
"iron": 7000,
|
||||
"stone": 7000
|
||||
},
|
||||
"time": 70
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"values": [
|
||||
80000
|
||||
],
|
||||
"need": {
|
||||
"decree": 0,
|
||||
"grain": 8000,
|
||||
"wood": 8000,
|
||||
"iron": 8000,
|
||||
"stone": 8000
|
||||
},
|
||||
"time": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
9205
data/conf/json/general/general.json
Normal file
9205
data/conf/json/general/general.json
Normal file
File diff suppressed because it is too large
Load Diff
117
data/conf/json/general/general_arms.json
Normal file
117
data/conf/json/general/general_arms.json
Normal file
@@ -0,0 +1,117 @@
|
||||
{
|
||||
"title": "兵种配置表",
|
||||
"arms":[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "步兵",
|
||||
"condition":{
|
||||
"level": 1,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 1000
|
||||
},
|
||||
"harm_ratio": [100, 110, 90, 95, 105, 85, 90, 100, 80]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "弓兵",
|
||||
"condition":{
|
||||
"level": 1,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 1000
|
||||
},
|
||||
"harm_ratio":[90, 100, 110, 85, 95, 105, 80, 90, 100]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "骑兵",
|
||||
"condition":{
|
||||
"level": 1,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 1000
|
||||
},
|
||||
"harm_ratio": [110, 90, 100, 105, 85, 95, 100, 80, 90]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "轻步兵",
|
||||
"condition":{
|
||||
"level": 3,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 5000
|
||||
},
|
||||
"harm_ratio": [105, 115, 95, 100, 110, 90, 95, 105, 85]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "长弓兵",
|
||||
"condition":{
|
||||
"level": 3,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 6000
|
||||
},
|
||||
"harm_ratio": [95, 105, 115, 90, 100, 110, 85, 95, 105]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "轻骑兵",
|
||||
"condition":{
|
||||
"level": 3,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 4000
|
||||
},
|
||||
"harm_ratio": [115, 95, 105, 110, 90, 100, 105, 85, 95]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "重甲兵",
|
||||
"condition":{
|
||||
"level": 7,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 14000
|
||||
},
|
||||
"harm_ratio": [110, 120, 90, 105, 115, 95, 100, 110, 90]
|
||||
},
|
||||
|
||||
{
|
||||
"id": 8,
|
||||
"name": "弩兵",
|
||||
"condition":{
|
||||
"level": 3,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 6000
|
||||
},
|
||||
"harm_ratio": [100, 110, 120, 95, 105, 115, 90, 100, 110]
|
||||
},
|
||||
|
||||
{
|
||||
"id": 9,
|
||||
"name": "重骑兵",
|
||||
"condition":{
|
||||
"level": 7,
|
||||
"star_lv": 0
|
||||
},
|
||||
"change_cost": {
|
||||
"gold": 18000
|
||||
},
|
||||
"harm_ratio": [120, 100, 110, 105, 95, 105, 110, 90, 100]
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
105
data/conf/json/general/general_basic.json
Normal file
105
data/conf/json/general/general_basic.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"title": "将领基本配置表",
|
||||
"levels":[
|
||||
{
|
||||
"level": 1,
|
||||
"exp": 0,
|
||||
"soldiers": 100
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"exp": 1000,
|
||||
"soldiers": 200
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"exp": 2000,
|
||||
"soldiers": 300
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"exp": 3000,
|
||||
"soldiers": 400
|
||||
},
|
||||
{
|
||||
"level": 5,
|
||||
"exp": 4000,
|
||||
"soldiers": 500
|
||||
},
|
||||
{
|
||||
"level": 6,
|
||||
"exp": 5000,
|
||||
"soldiers": 600
|
||||
},
|
||||
{
|
||||
"level": 7,
|
||||
"exp": 6000,
|
||||
"soldiers": 700
|
||||
},
|
||||
{
|
||||
"level": 8,
|
||||
"exp": 7500,
|
||||
"soldiers": 800
|
||||
},
|
||||
{
|
||||
"level": 9,
|
||||
"exp": 9000,
|
||||
"soldiers": 900
|
||||
},
|
||||
{
|
||||
"level": 10,
|
||||
"exp": 11000,
|
||||
"soldiers": 1000
|
||||
},
|
||||
{
|
||||
"level": 11,
|
||||
"exp": 12500,
|
||||
"soldiers": 1100
|
||||
},
|
||||
{
|
||||
"level": 12,
|
||||
"exp": 15000,
|
||||
"soldiers": 1200
|
||||
},
|
||||
{
|
||||
"level": 13,
|
||||
"exp": 17000,
|
||||
"soldiers": 1300
|
||||
},
|
||||
{
|
||||
"level": 14,
|
||||
"exp": 19000,
|
||||
"soldiers": 1400
|
||||
},
|
||||
{
|
||||
"level": 15,
|
||||
"exp": 23000,
|
||||
"soldiers": 1500
|
||||
}, {
|
||||
"level": 16,
|
||||
"exp": 26000,
|
||||
"soldiers": 1600
|
||||
},
|
||||
{
|
||||
"level": 17,
|
||||
"exp": 29000,
|
||||
"soldiers": 1700
|
||||
},
|
||||
{
|
||||
"level": 18,
|
||||
"exp": 31000,
|
||||
"soldiers": 1800
|
||||
},
|
||||
{
|
||||
"level": 19,
|
||||
"exp": 35000,
|
||||
"soldiers": 1900
|
||||
},
|
||||
{
|
||||
"level": 20,
|
||||
"exp": 50000,
|
||||
"soldiers": 2000
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
439
data/conf/json/map_build.json
Normal file
439
data/conf/json/map_build.json
Normal file
@@ -0,0 +1,439 @@
|
||||
{
|
||||
"title": "地图资源配置",
|
||||
"cfg":[
|
||||
{"type": 50,
|
||||
"des": "系统要塞",
|
||||
"name": "要塞",
|
||||
"level": 5,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 30000,
|
||||
"defender": 1
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 1,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 100000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 2,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 200000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 3,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 300000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 4,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 400000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 5,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 500000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 6,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 600000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 7,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 700000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 8,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 800000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 9,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 900000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 51,
|
||||
"name": "城区",
|
||||
"level": 10,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 1000000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.1",
|
||||
"level": 1,
|
||||
"grain": 100,
|
||||
"wood": 100,
|
||||
"iron": 100,
|
||||
"stone": 100,
|
||||
"durable": 10000,
|
||||
"defender": 1
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.2",
|
||||
"level": 2,
|
||||
"grain": 200,
|
||||
"wood": 200,
|
||||
"iron": 200,
|
||||
"stone": 200,
|
||||
"durable": 10000,
|
||||
"defender": 2
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.3",
|
||||
"level": 3,
|
||||
"grain": 300,
|
||||
"wood": 300,
|
||||
"iron": 300,
|
||||
"stone": 300,
|
||||
"durable": 100,
|
||||
"defender": 3
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.4",
|
||||
"level": 4,
|
||||
"grain": 0,
|
||||
"wood": 4000,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 4
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.5",
|
||||
"level": 5,
|
||||
"grain": 0,
|
||||
"wood": 5000,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.6",
|
||||
"level": 6,
|
||||
"grain": 0,
|
||||
"wood": 1000,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 6
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.7",
|
||||
"level": 7,
|
||||
"grain": 0,
|
||||
"wood": 2000,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 7
|
||||
},
|
||||
{"type": 52,
|
||||
"name": "土地Lv.8",
|
||||
"level": 8,
|
||||
"grain": 0,
|
||||
"wood": 3000,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 100,
|
||||
"defender": 8
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.1",
|
||||
"level": 1,
|
||||
"grain": 100,
|
||||
"wood": 100,
|
||||
"iron": 100,
|
||||
"stone": 100,
|
||||
"durable": 10000,
|
||||
"defender": 1
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.2",
|
||||
"level": 2,
|
||||
"grain": 200,
|
||||
"wood": 200,
|
||||
"iron": 200,
|
||||
"stone": 200,
|
||||
"durable": 10000,
|
||||
"defender": 2
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.3",
|
||||
"level": 3,
|
||||
"grain": 300,
|
||||
"wood": 300,
|
||||
"iron": 300,
|
||||
"stone": 300,
|
||||
"durable": 100,
|
||||
"defender": 3
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.4",
|
||||
"level": 4,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 4000,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 4
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.5",
|
||||
"level": 5,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 5000,
|
||||
"stone": 0,
|
||||
"durable": 100,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.6",
|
||||
"level": 6,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 6000,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 6
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.7",
|
||||
"level": 7,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 7000,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 7
|
||||
},
|
||||
{"type": 53,
|
||||
"name": "土地Lv.8",
|
||||
"level": 8,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 8000,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 8
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.1",
|
||||
"level": 1,
|
||||
"grain": 100,
|
||||
"wood": 100,
|
||||
"iron": 100,
|
||||
"stone": 100,
|
||||
"durable": 10000,
|
||||
"defender": 1
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.2",
|
||||
"level": 2,
|
||||
"grain": 200,
|
||||
"wood": 200,
|
||||
"iron": 200,
|
||||
"stone": 200,
|
||||
"durable": 10000,
|
||||
"defender": 2
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.3",
|
||||
"level": 3,
|
||||
"grain": 300,
|
||||
"wood": 300,
|
||||
"iron": 300,
|
||||
"stone": 300,
|
||||
"durable": 100,
|
||||
"defender": 3
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.4",
|
||||
"level": 4,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 1000,
|
||||
"durable": 10000,
|
||||
"defender": 1
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.5",
|
||||
"level": 5,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 5000,
|
||||
"durable": 10000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.6",
|
||||
"level": 6,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 6000,
|
||||
"durable": 10000,
|
||||
"defender": 6
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.7",
|
||||
"level": 7,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 7000,
|
||||
"durable": 10000,
|
||||
"defender": 7
|
||||
},
|
||||
{"type": 54,
|
||||
"name": "土地Lv.8",
|
||||
"level": 8,
|
||||
"grain": 0,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 8000,
|
||||
"durable": 10000,
|
||||
"defender": 8
|
||||
},
|
||||
|
||||
|
||||
|
||||
{"type": 55,
|
||||
"name": "土地Lv.1",
|
||||
"level": 1,
|
||||
"grain": 100,
|
||||
"wood": 100,
|
||||
"iron": 100,
|
||||
"stone": 100,
|
||||
"durable": 10000,
|
||||
"defender": 1
|
||||
},
|
||||
{"type": 55,
|
||||
"name": "土地Lv.2",
|
||||
"level": 2,
|
||||
"grain": 200,
|
||||
"wood": 200,
|
||||
"iron": 200,
|
||||
"stone": 200,
|
||||
"durable": 10000,
|
||||
"defender": 2
|
||||
},
|
||||
{"type": 55,
|
||||
"name": "土地Lv.3",
|
||||
"level": 3,
|
||||
"grain": 300,
|
||||
"wood": 300,
|
||||
"iron": 300,
|
||||
"stone": 300,
|
||||
"durable": 100,
|
||||
"defender": 3
|
||||
},
|
||||
{"type": 55,
|
||||
"name": "土地Lv.4",
|
||||
"level": 4,
|
||||
"grain": 1000,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 4
|
||||
},
|
||||
{"type": 55,
|
||||
"name": "土地Lv.5",
|
||||
"level": 5,
|
||||
"grain": 5000,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 5
|
||||
},
|
||||
{"type": 55,
|
||||
"name": "土地Lv.6",
|
||||
"level": 6,
|
||||
"grain": 6000,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 6
|
||||
},
|
||||
{"type": 55,
|
||||
"name": "土地Lv.7",
|
||||
"level": 7,
|
||||
"grain": 7000,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 7
|
||||
},
|
||||
{"type": 55,
|
||||
"name": "土地Lv.8",
|
||||
"level": 8,
|
||||
"grain": 8000,
|
||||
"wood": 0,
|
||||
"iron": 0,
|
||||
"stone": 0,
|
||||
"durable": 10000,
|
||||
"defender": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
43
data/conf/json/map_build_custom.json
Normal file
43
data/conf/json/map_build_custom.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"title": "地图用户建设的建筑配置",
|
||||
"cfg": [
|
||||
{
|
||||
"type": 56,
|
||||
"name": "要塞",
|
||||
"levels": [
|
||||
{
|
||||
"level": 1,
|
||||
"durable": 10000,
|
||||
"defender": 5,
|
||||
"time": 20,
|
||||
"need": {
|
||||
"decree": 2,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"result": {
|
||||
"army_cnt": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"durable": 10000,
|
||||
"defender": 5,
|
||||
"time": 20,
|
||||
"need": {
|
||||
"decree": 3,
|
||||
"grain": 1000,
|
||||
"wood": 1000,
|
||||
"iron": 1000,
|
||||
"stone": 1000
|
||||
},
|
||||
"result": {
|
||||
"army_cnt": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
75
data/conf/json/skill/beidong/baizhanjingbing.json
Normal file
75
data/conf/json/skill/beidong/baizhanjingbing.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"cfgId": 201,
|
||||
"name": "百战精兵",
|
||||
"trigger": 2,
|
||||
"target": 2,
|
||||
"des": "使自身攻击属性提升%n%、防御属性提升%n%、谋略属性提升%n%、速度属性提升%n%",
|
||||
"limit": 3,
|
||||
"arms": [
|
||||
1,
|
||||
4,
|
||||
7,
|
||||
2,
|
||||
5,
|
||||
8,
|
||||
3,
|
||||
6,
|
||||
9
|
||||
],
|
||||
|
||||
"include_effect": [
|
||||
2,3,4,5
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50,50,50,50],
|
||||
"effect_round": [0]
|
||||
}
|
||||
]
|
||||
}
|
||||
90
data/conf/json/skill/skill_outline.json
Normal file
90
data/conf/json/skill/skill_outline.json
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"trigger_type": {
|
||||
"des": "触发类型",
|
||||
"list": [
|
||||
{
|
||||
"type": 1,
|
||||
"des": "主动"
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"des": "被动"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"des": "追击"
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"des": "指挥"
|
||||
}
|
||||
]
|
||||
},
|
||||
"effect_type": {
|
||||
"des": "效果类型",
|
||||
"list": [
|
||||
{
|
||||
"type": 1,
|
||||
"des": "伤害率",
|
||||
"isRate": true
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"des": "攻击",
|
||||
"isRate": false
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"des": "防御",
|
||||
"isRate": false
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"des": "谋略",
|
||||
"isRate": false
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"des": "速度",
|
||||
"isRate": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"target_type": {
|
||||
"des": "作用目标类型",
|
||||
"list": [
|
||||
{
|
||||
"type": 1,
|
||||
"des": "自己"
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"des": "我军单体"
|
||||
},
|
||||
{
|
||||
"type": 3,
|
||||
"des": "我军1-2个目标"
|
||||
},
|
||||
{
|
||||
"type": 4,
|
||||
"des": "我军全体"
|
||||
},
|
||||
{
|
||||
"type": 5,
|
||||
"des": "敌军单体"
|
||||
},
|
||||
{
|
||||
"type": 6,
|
||||
"des": "敌军1-2个目标"
|
||||
},
|
||||
{
|
||||
"type": 7,
|
||||
"des": "敌军2-3个目标"
|
||||
},
|
||||
{
|
||||
"type": 8,
|
||||
"des": "敌军全体"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
72
data/conf/json/skill/zhihui/fengshi.json
Normal file
72
data/conf/json/skill/zhihui/fengshi.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"cfgId": 401,
|
||||
"name": "锋矢",
|
||||
"trigger": 4,
|
||||
"target": 2,
|
||||
"des": "战斗中,使我军全体进行普通攻击的伤害提升%n%",
|
||||
"limit": 3,
|
||||
"arms": [
|
||||
2,
|
||||
5,
|
||||
8,
|
||||
3,
|
||||
6,
|
||||
9
|
||||
],
|
||||
|
||||
"include_effect": [
|
||||
1
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
}
|
||||
]
|
||||
}
|
||||
72
data/conf/json/skill/zhudong/tuji.json
Normal file
72
data/conf/json/skill/zhudong/tuji.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"cfgId": 101,
|
||||
"name": "突击",
|
||||
"trigger": 1,
|
||||
"target": 5,
|
||||
"des": "对敌军单体发动一次攻击(伤害率`%n%%`)",
|
||||
"limit": 3,
|
||||
"arms": [
|
||||
1,
|
||||
4,
|
||||
7,
|
||||
3,
|
||||
6,
|
||||
9
|
||||
],
|
||||
|
||||
"include_effect": [
|
||||
1
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
}
|
||||
]
|
||||
}
|
||||
72
data/conf/json/skill/zhuiji/zhongzhan.json
Normal file
72
data/conf/json/skill/zhuiji/zhongzhan.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"cfgId": 301,
|
||||
"name": "重斩",
|
||||
"trigger": 3,
|
||||
"target": 5,
|
||||
"des": "普通攻击后,对攻击目标再次发动攻击(伤害率%n%%)",
|
||||
"limit": 3,
|
||||
"arms": [
|
||||
1,
|
||||
4,
|
||||
7,
|
||||
3,
|
||||
6,
|
||||
9
|
||||
],
|
||||
|
||||
"include_effect": [
|
||||
1
|
||||
],
|
||||
"levels": [
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
},
|
||||
{
|
||||
"probability":30,
|
||||
"effect_value": [50],
|
||||
"effect_round": [0]
|
||||
}
|
||||
]
|
||||
}
|
||||
1
data/conf/mapRes_0.json
Normal file
1
data/conf/mapRes_0.json
Normal file
File diff suppressed because one or more lines are too long
155
db/conn.go
Normal file
155
db/conn.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slgserver/config"
|
||||
"time"
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/log"
|
||||
)
|
||||
|
||||
var MasterDB *xorm.Engine
|
||||
|
||||
var logFileHandle *os.File
|
||||
|
||||
var (
|
||||
ConnectDBErr = errors.New("connect db error")
|
||||
UseDBErr = errors.New("use db error")
|
||||
)
|
||||
|
||||
// TestDB 测试数据库
|
||||
func TestDB() error {
|
||||
mysqlConfig, err := config.GetSection("mysql")
|
||||
if err != nil {
|
||||
slog.Error("get mysql config error", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tmpDns := fmt.Sprintf("%s:%s@tcp(%s:%s)/?charset=%s&parseTime=True&loc=Local",
|
||||
mysqlConfig["user"],
|
||||
mysqlConfig["password"],
|
||||
mysqlConfig["host"],
|
||||
mysqlConfig["port"],
|
||||
mysqlConfig["charset"])
|
||||
egnine, err := xorm.NewEngine("mysql", tmpDns)
|
||||
if err != nil {
|
||||
slog.Error("new engine error", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
defer egnine.Close()
|
||||
|
||||
// 测试数据库连接是否 OK
|
||||
if err = egnine.Ping(); err != nil {
|
||||
slog.Error("ping db error", "error", err)
|
||||
return ConnectDBErr
|
||||
}
|
||||
|
||||
_, err = egnine.Exec("use " + mysqlConfig["dbname"])
|
||||
if err != nil {
|
||||
slog.Error("use db error", "error", err)
|
||||
// 使用参数化查询避免SQL注入风险
|
||||
createDBQuery := fmt.Sprintf("CREATE DATABASE `%s` DEFAULT CHARACTER SET %s", mysqlConfig["dbname"], mysqlConfig["charset"])
|
||||
_, err = egnine.Exec(createDBQuery)
|
||||
if err != nil {
|
||||
slog.Error("create database error", "error", err)
|
||||
|
||||
return UseDBErr
|
||||
}
|
||||
|
||||
slog.Info("create database successfully")
|
||||
}
|
||||
|
||||
// 初始化 MasterDB
|
||||
return Init()
|
||||
}
|
||||
|
||||
func Init() error {
|
||||
mysqlConfig, err := config.GetSection("mysql")
|
||||
if err != nil {
|
||||
slog.Error("get mysql config error", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 启动时就打开数据库连接
|
||||
if err = initEngine(mysqlConfig); err != nil {
|
||||
slog.Error("mysql is not open", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fillDns(mysqlConfig map[string]string) string {
|
||||
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local",
|
||||
mysqlConfig["user"],
|
||||
mysqlConfig["password"],
|
||||
mysqlConfig["host"],
|
||||
mysqlConfig["port"],
|
||||
mysqlConfig["dbname"],
|
||||
mysqlConfig["charset"])
|
||||
}
|
||||
|
||||
func initEngine(mysqlConfig map[string]string) error {
|
||||
|
||||
var err error
|
||||
dns := fillDns(mysqlConfig)
|
||||
|
||||
MasterDB, err = xorm.NewEngine("mysql", dns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 数据库连接池配置,根据实际负载调整
|
||||
maxIdle := config.GetInt("mysql.max_idle", 10) // 默认值从2提升到10
|
||||
maxConn := config.GetInt("mysql.max_conn", 100) // 默认值从10提升到100
|
||||
|
||||
MasterDB.SetMaxIdleConns(maxIdle)
|
||||
MasterDB.SetMaxOpenConns(maxConn)
|
||||
|
||||
// 设置连接最大生存时间,避免长时间连接导致的问题
|
||||
MasterDB.SetConnMaxLifetime(time.Hour)
|
||||
|
||||
showSQL := config.GetBool("xorm.show_sql", false)
|
||||
logLevel := config.GetInt("xorm.log_level", 1)
|
||||
logFile := config.GetPath("xorm.log_file", "")
|
||||
|
||||
if logFile != "" {
|
||||
if logFileHandle != nil {
|
||||
logFileHandle.Close()
|
||||
}
|
||||
// 确保日志文件目录存在
|
||||
if err := os.MkdirAll(filepath.Dir(logFile), 0755); err != nil {
|
||||
return fmt.Errorf("failed to create log directory: %w", err)
|
||||
}
|
||||
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logFileHandle = f
|
||||
MasterDB.SetLogger(log.NewSimpleLogger(f))
|
||||
}
|
||||
|
||||
MasterDB.SetLogLevel(log.LogLevel(logLevel))
|
||||
MasterDB.ShowSQL(showSQL)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func StdMasterDB() *sql.DB {
|
||||
return MasterDB.DB().DB
|
||||
}
|
||||
|
||||
func Close() {
|
||||
if MasterDB != nil {
|
||||
MasterDB.Close()
|
||||
}
|
||||
if logFileHandle != nil {
|
||||
logFileHandle.Close()
|
||||
}
|
||||
}
|
||||
60
go.mod
Normal file
60
go.mod
Normal file
@@ -0,0 +1,60 @@
|
||||
module slgserver
|
||||
|
||||
go 1.25
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/go-sql-driver/mysql v1.9.3
|
||||
github.com/go-think/openssl v1.20.0
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/spf13/viper v1.21.0
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
xorm.io/xorm v1.3.11
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic v1.14.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.4.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.11 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.28.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.56.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.23.0 // indirect
|
||||
golang.org/x/crypto v0.44.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
xorm.io/builder v0.3.13 // indirect
|
||||
)
|
||||
200
go.sum
Normal file
200
go.sum
Normal file
@@ -0,0 +1,200 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
|
||||
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
|
||||
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
|
||||
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
|
||||
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
|
||||
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-think/openssl v1.20.0 h1:awyPzo559r0eOePQ35jLwXVjY0hws/2et+9OHQCEUZc=
|
||||
github.com/go-think/openssl v1.20.0/go.mod h1:Ug+hrHD5ldaCqpHVuSaP1z/HogGbEtXEbUJmiHai+II=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs=
|
||||
github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.56.0 h1:q/TW+OLismmXAehgFLczhCDTYB3bFmua4D9lsNBWxvY=
|
||||
github.com/quic-go/quic-go v0.56.0/go.mod h1:9gx5KsFQtw2oZ6GZTyh+7YEvOxWCL9WZAepnHxgAo6c=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
|
||||
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg=
|
||||
golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
|
||||
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.20.4 h1:J8+m2trkN+KKoE7jglyHYYYiaq5xmz2HoHJIiBlRzbE=
|
||||
modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
|
||||
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/xorm v1.3.11 h1:i4tlVUASogb0ZZFJHA7dZqoRU2pUpUsutnNdaOlFyMI=
|
||||
xorm.io/xorm v1.3.11/go.mod h1:cs0ePc8O4a0jD78cNvD+0VFwhqotTvLQZv372QsDw7Q=
|
||||
46
log/log.go
Normal file
46
log/log.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slgserver/config"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
fileDir := config.GetString("log.file_dir", "../log/")
|
||||
maxSize := config.GetInt("log.max_size", 128)
|
||||
maxBackups := config.GetInt("log.max_backups", 30)
|
||||
maxAge := config.GetInt("log.max_age", 7)
|
||||
compress := config.GetBool("log.compress", true)
|
||||
|
||||
sa := strings.Split(filepath.Base(os.Args[0]), ".")
|
||||
fileName := sa[0] + ".log"
|
||||
hook := &lumberjack.Logger{
|
||||
Filename: path.Join(fileDir, fileName), // 日志文件路径
|
||||
MaxSize: maxSize, // 每个日志文件保存的最大尺寸 单位:M
|
||||
MaxBackups: maxBackups, // 日志文件最多保存多少个备份
|
||||
MaxAge: maxAge, // 文件最多保存多少天
|
||||
Compress: compress, // 是否压缩
|
||||
}
|
||||
|
||||
// 创建多写入器:同时写入标准输出和文件
|
||||
multiWriter := io.MultiWriter(os.Stdout, hook)
|
||||
|
||||
// 创建 JSON handler,包含调用者信息
|
||||
opts := &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
AddSource: true, // 添加调用者信息
|
||||
}
|
||||
|
||||
handler := slog.NewJSONHandler(multiWriter, opts)
|
||||
logger := slog.New(handler)
|
||||
|
||||
// 使用 slog 标准方式设置默认 logger
|
||||
slog.SetDefault(logger)
|
||||
}
|
||||
BIN
main/chatserver.exe
Normal file
BIN
main/chatserver.exe
Normal file
Binary file not shown.
28
main/chatserver.go
Normal file
28
main/chatserver.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"slgserver/config"
|
||||
"slgserver/net"
|
||||
"slgserver/server/chatserver"
|
||||
)
|
||||
|
||||
func getChatServerAddr() string {
|
||||
host := config.GetString("chatserver.host", "")
|
||||
port := config.GetString("chatserver.port", "8002")
|
||||
return host + ":" + port
|
||||
}
|
||||
|
||||
func main() {
|
||||
if wd, err := os.Getwd(); err == nil {
|
||||
slog.Info("working directory", "dir", wd)
|
||||
} else {
|
||||
slog.Warn("get working directory failed", "error", err)
|
||||
}
|
||||
chatserver.Init()
|
||||
needSecret := config.GetBool("chatserver.need_secret", false)
|
||||
s := net.NewServer(getChatServerAddr(), needSecret)
|
||||
s.Router(chatserver.MyRouter)
|
||||
s.Start()
|
||||
}
|
||||
BIN
main/gateserver.exe
Normal file
BIN
main/gateserver.exe
Normal file
Binary file not shown.
30
main/gateserver.go
Normal file
30
main/gateserver.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"slgserver/config"
|
||||
"slgserver/net"
|
||||
"slgserver/server/gateserver"
|
||||
"slgserver/server/gateserver/controller"
|
||||
)
|
||||
|
||||
func getGateServerAddr() string {
|
||||
host := config.GetString("gateserver.host", "")
|
||||
port := config.GetString("gateserver.port", "8004")
|
||||
return host + ":" + port
|
||||
}
|
||||
|
||||
func main() {
|
||||
if wd, err := os.Getwd(); err == nil {
|
||||
slog.Info("working directory", "dir", wd)
|
||||
} else {
|
||||
slog.Warn("get working directory failed", "error", err)
|
||||
}
|
||||
gateserver.Init()
|
||||
needSecret := config.GetBool("gateserver.need_secret", false)
|
||||
s := net.NewServer(getGateServerAddr(), needSecret)
|
||||
s.Router(gateserver.MyRouter)
|
||||
s.SetOnBeforeClose(controller.GHandle.OnServerConnClose)
|
||||
s.Start()
|
||||
}
|
||||
BIN
main/httpserver.exe
Normal file
BIN
main/httpserver.exe
Normal file
Binary file not shown.
29
main/httpserver.go
Normal file
29
main/httpserver.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"slgserver/config"
|
||||
"slgserver/db"
|
||||
"slgserver/server/httpserver/controller"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 设置 Gin 为 release 模式
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
db.TestDB()
|
||||
|
||||
r := gin.Default()
|
||||
|
||||
g := r.Group("")
|
||||
new(controller.AccountController).RegisterRoutes(g)
|
||||
|
||||
addr := getHttpAddr()
|
||||
r.Run(addr)
|
||||
}
|
||||
|
||||
func getHttpAddr() string {
|
||||
host := config.GetString("httpserver.host", "")
|
||||
port := config.GetString("httpserver.port", "8088")
|
||||
return host + ":" + port
|
||||
}
|
||||
BIN
main/loginserver.exe
Normal file
BIN
main/loginserver.exe
Normal file
Binary file not shown.
28
main/loginserver.go
Normal file
28
main/loginserver.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"slgserver/config"
|
||||
"slgserver/net"
|
||||
"slgserver/server/loginserver"
|
||||
)
|
||||
|
||||
func getLoginServerAddr() string {
|
||||
host := config.GetString("loginserver.host", "")
|
||||
port := config.GetString("loginserver.port", "8003")
|
||||
return host + ":" + port
|
||||
}
|
||||
|
||||
func main() {
|
||||
if wd, err := os.Getwd(); err == nil {
|
||||
slog.Info("working directory", "dir", wd)
|
||||
} else {
|
||||
slog.Warn("get working directory failed", "error", err)
|
||||
}
|
||||
loginserver.Init()
|
||||
needSecret := config.GetBool("loginserver.need_secret", false)
|
||||
s := net.NewServer(getLoginServerAddr(), needSecret)
|
||||
s.Router(loginserver.MyRouter)
|
||||
s.Start()
|
||||
}
|
||||
BIN
main/slgserver.exe
Normal file
BIN
main/slgserver.exe
Normal file
Binary file not shown.
28
main/slgserver.go
Normal file
28
main/slgserver.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"slgserver/config"
|
||||
"slgserver/net"
|
||||
"slgserver/server/slgserver/run"
|
||||
)
|
||||
|
||||
func getServerAddr() string {
|
||||
host := config.GetString("slgserver.host", "")
|
||||
port := config.GetString("slgserver.port", "8001")
|
||||
return host + ":" + port
|
||||
}
|
||||
|
||||
func main() {
|
||||
if wd, err := os.Getwd(); err == nil {
|
||||
slog.Info("working directory", "dir", wd)
|
||||
} else {
|
||||
slog.Warn("get working directory failed", "error", err)
|
||||
}
|
||||
run.Init()
|
||||
needSecret := config.GetBool("slgserver.need_secret", false)
|
||||
s := net.NewServer(getServerAddr(), needSecret)
|
||||
s.Router(run.MyRouter)
|
||||
s.Start()
|
||||
}
|
||||
125
main/wstest.go
Normal file
125
main/wstest.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/go-think/openssl"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/gorilla/websocket"
|
||||
"log/slog"
|
||||
"slgserver/net"
|
||||
proto2 "slgserver/server/loginserver/proto"
|
||||
"slgserver/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
var origin = "httpserver://127.0.0.1:8002/"
|
||||
var secretKey = []byte("")
|
||||
var session = ""
|
||||
|
||||
func main() {
|
||||
|
||||
var dialer *websocket.Dialer
|
||||
//通过Dialer连接websocket服务器
|
||||
conn, _, err := dialer.Dial("ws://127.0.0.1:8001", nil)
|
||||
if err != nil {
|
||||
slog.Error("dial websocket failed", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
go do(conn)
|
||||
go timeWriter(conn)
|
||||
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
|
||||
func do(conn *websocket.Conn) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
slog.Error("do panic", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
_, message, _ := conn.ReadMessage()
|
||||
msg := &net.RspBody{}
|
||||
if len(secretKey) == 0 {
|
||||
message, _ = util.UnZip(message)
|
||||
if err := util.Unmarshal(message, msg); err == nil {
|
||||
if msg.Name == "handshake" {
|
||||
h := &net.Handshake{}
|
||||
mapstructure.Decode(msg.Msg, h)
|
||||
|
||||
secretKey = []byte(h.Key)
|
||||
}
|
||||
slog.Info("received message", "name", msg.Name)
|
||||
}
|
||||
} else {
|
||||
message, _ = util.UnZip(message)
|
||||
data, err := util.AesCBCDecrypt(message, secretKey, secretKey, openssl.ZEROS_PADDING)
|
||||
if err == nil {
|
||||
if err := util.Unmarshal(data, msg); err == nil {
|
||||
slog.Info("received message",
|
||||
"name", msg.Name,
|
||||
"code", msg.Code,
|
||||
"payload", msg.Msg)
|
||||
if msg.Name == "login" {
|
||||
lr := &proto2.LoginRsp{}
|
||||
mapstructure.Decode(msg.Msg, lr)
|
||||
session = lr.Session
|
||||
}
|
||||
} else {
|
||||
secretKey = []byte("")
|
||||
}
|
||||
} else {
|
||||
secretKey = []byte("")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func login(conn *websocket.Conn) {
|
||||
l := &proto2.LoginReq{Ip: "127.0.0.1", Username: "test", Password: "123456"}
|
||||
send(conn, "login", l)
|
||||
}
|
||||
|
||||
func reLogin(conn *websocket.Conn, session string) {
|
||||
l := &proto2.ReLoginReq{Session: session}
|
||||
slog.Info("relogin session", "session", session)
|
||||
send(conn, "reLogin", l)
|
||||
}
|
||||
|
||||
func logout(conn *websocket.Conn) {
|
||||
l := &proto2.LogoutReq{UId: 5}
|
||||
send(conn, "logout", l)
|
||||
}
|
||||
|
||||
func send(conn *websocket.Conn, name string, dd interface{}) {
|
||||
msg := &net.ReqBody{Name: name, Msg: dd}
|
||||
|
||||
if len(secretKey) == 0 {
|
||||
|
||||
} else {
|
||||
if data, err := util.Marshal(msg); err == nil {
|
||||
data, _ := util.AesCBCEncrypt(data, secretKey, secretKey, openssl.ZEROS_PADDING)
|
||||
data, _ = util.Zip(data)
|
||||
|
||||
conn.WriteMessage(websocket.BinaryMessage, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func timeWriter(conn *websocket.Conn) {
|
||||
|
||||
time.Sleep(time.Second * 1)
|
||||
login(conn)
|
||||
|
||||
time.Sleep(time.Second * 1)
|
||||
reLogin(conn, session)
|
||||
|
||||
time.Sleep(20 * time.Second)
|
||||
|
||||
//time.Sleep(time.Second * 1)
|
||||
//reLogin(conn, "123")
|
||||
//
|
||||
//time.Sleep(time.Second * 1)
|
||||
//logout(conn)
|
||||
}
|
||||
25
middleware/check_login.go
Normal file
25
middleware/check_login.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/net"
|
||||
)
|
||||
|
||||
func CheckLogin() net.MiddlewareFunc {
|
||||
return func(next net.HandlerFunc) net.HandlerFunc {
|
||||
return func(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
_, err := req.Conn.GetProperty("uid")
|
||||
if err != nil {
|
||||
slog.Warn("connect not found uid",
|
||||
"msgName", req.Body.Name)
|
||||
rsp.Body.Code = constant.UserNotInConnect
|
||||
req.Conn.Push("account.pleaseLogin", nil)
|
||||
return
|
||||
}
|
||||
|
||||
next(req, rsp)
|
||||
}
|
||||
}
|
||||
}
|
||||
23
middleware/check_rid.go
Normal file
23
middleware/check_rid.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/net"
|
||||
)
|
||||
|
||||
func CheckRId() net.MiddlewareFunc {
|
||||
return func(next net.HandlerFunc) net.HandlerFunc {
|
||||
return func(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
_, err := req.Conn.GetProperty("rid")
|
||||
if err != nil {
|
||||
rsp.Body.Code = constant.RoleNotInConnect
|
||||
slog.Warn("connect not found role",
|
||||
"msgName", req.Body.Name)
|
||||
return
|
||||
}
|
||||
next(req, rsp)
|
||||
}
|
||||
}
|
||||
}
|
||||
23
middleware/check_role.go
Normal file
23
middleware/check_role.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/net"
|
||||
)
|
||||
|
||||
func CheckRole() net.MiddlewareFunc {
|
||||
return func(next net.HandlerFunc) net.HandlerFunc {
|
||||
return func(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
_, err := req.Conn.GetProperty("role")
|
||||
if err != nil {
|
||||
rsp.Body.Code = constant.RoleNotInConnect
|
||||
slog.Warn("connect not found role",
|
||||
"msgName", req.Body.Name)
|
||||
return
|
||||
}
|
||||
next(req, rsp)
|
||||
}
|
||||
}
|
||||
}
|
||||
23
middleware/elapsed_time.go
Normal file
23
middleware/elapsed_time.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/net"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ElapsedTime() net.MiddlewareFunc {
|
||||
return func(next net.HandlerFunc) net.HandlerFunc {
|
||||
return func(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
bt := time.Now().UnixNano()
|
||||
next(req, rsp)
|
||||
et := time.Now().UnixNano()
|
||||
diff := (et - bt)/int64(time.Millisecond)
|
||||
|
||||
slog.Info("ElapsedTime:",
|
||||
"msgName", req.Body.Name,
|
||||
"cost", fmt.Sprintf("%dms", diff))
|
||||
}
|
||||
}
|
||||
}
|
||||
20
middleware/log.go
Normal file
20
middleware/log.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/net"
|
||||
)
|
||||
|
||||
func Log() net.MiddlewareFunc {
|
||||
return func(next net.HandlerFunc) net.HandlerFunc {
|
||||
return func(req *net.WsMsgReq, rsp *net.WsMsgRsp) {
|
||||
|
||||
slog.Info("client req",
|
||||
"msgName", req.Body.Name,
|
||||
"data", fmt.Sprintf("%v", req.Body.Msg))
|
||||
|
||||
next(req, rsp)
|
||||
}
|
||||
}
|
||||
}
|
||||
254
net/clientconn.go
Normal file
254
net/clientconn.go
Normal file
@@ -0,0 +1,254 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-think/openssl"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/gorilla/websocket"
|
||||
"log/slog"
|
||||
"slgserver/constant"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 客户端连接
|
||||
type ClientConn struct {
|
||||
wsSocket *websocket.Conn // 底层websocket
|
||||
isClosed bool
|
||||
Seq int64
|
||||
onClose func(conn*ClientConn)
|
||||
onPush func(conn*ClientConn, body*RspBody)
|
||||
//链接属性
|
||||
property map[string]interface{}
|
||||
//保护链接属性修改的锁
|
||||
propertyLock sync.RWMutex
|
||||
syncCtxs map[int64]*syncCtx
|
||||
syncLock sync.RWMutex
|
||||
handshakeChan chan bool
|
||||
handshake bool
|
||||
}
|
||||
|
||||
func NewClientConn(wsSocket *websocket.Conn) *ClientConn {
|
||||
conn := &ClientConn{
|
||||
wsSocket: wsSocket,
|
||||
isClosed: false,
|
||||
property: make(map[string]interface{}),
|
||||
Seq: 0,
|
||||
syncCtxs: make(map[int64]*syncCtx),
|
||||
handshakeChan: make(chan bool),
|
||||
}
|
||||
|
||||
return conn
|
||||
}
|
||||
|
||||
func (this *ClientConn) waitHandshake() bool{
|
||||
if this.handshake == false{
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
select {
|
||||
case _ = <-this.handshakeChan:{
|
||||
slog.Info("recv handshakeChan")
|
||||
return true
|
||||
}
|
||||
case <-ctx.Done():{
|
||||
slog.Info("recv handshakeChan timeout")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *ClientConn) Start() bool{
|
||||
this.handshake = false
|
||||
go this.wsReadLoop()
|
||||
return this.waitHandshake()
|
||||
}
|
||||
|
||||
func (this *ClientConn) Addr() string {
|
||||
return this.wsSocket.RemoteAddr().String()
|
||||
}
|
||||
|
||||
func (this *ClientConn) Push(name string, data interface{}) {
|
||||
rsp := &WsMsgRsp{Body: &RspBody{Name: name, Msg: data, Seq: 0}}
|
||||
this.write(rsp.Body)
|
||||
}
|
||||
|
||||
func (this *ClientConn) Send(name string, data interface{}) *RspBody{
|
||||
this.syncLock.Lock()
|
||||
sync := newSyncCtx()
|
||||
this.Seq += 1
|
||||
seq := this.Seq
|
||||
req := ReqBody{Name: name, Msg: data, Seq: seq}
|
||||
this.syncCtxs[this.Seq] = sync
|
||||
this.syncLock.Unlock()
|
||||
|
||||
rsp := &RspBody{Code: constant.OK, Name: name, Seq: seq }
|
||||
err := this.write(req)
|
||||
if err != nil{
|
||||
sync.cancel()
|
||||
}else{
|
||||
r := sync.wait()
|
||||
if r == nil{
|
||||
rsp.Code = constant.ProxyConnectError
|
||||
}else{
|
||||
rsp = r
|
||||
}
|
||||
}
|
||||
|
||||
this.syncLock.Lock()
|
||||
delete(this.syncCtxs, seq)
|
||||
this.syncLock.Unlock()
|
||||
|
||||
return rsp
|
||||
}
|
||||
|
||||
func (this *ClientConn) wsReadLoop() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
e := fmt.Sprintf("%v", err)
|
||||
slog.Error("wsReadLoop error", "err", e)
|
||||
this.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
// 读一个message
|
||||
_, data, err := this.wsSocket.ReadMessage()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
data, err = util.UnZip(data)
|
||||
if err != nil {
|
||||
slog.Error("wsReadLoop UnZip error", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
//需要检测是否有加密
|
||||
body := &RspBody{}
|
||||
if secretKey, err := this.GetProperty("secretKey"); err == nil {
|
||||
key := secretKey.(string)
|
||||
d, err := util.AesCBCDecrypt(data, []byte(key), []byte(key), openssl.ZEROS_PADDING)
|
||||
if err != nil {
|
||||
slog.Error("AesDecrypt error", "error", err)
|
||||
}else{
|
||||
data = d
|
||||
}
|
||||
}
|
||||
|
||||
if err := util.Unmarshal(data, body); err == nil {
|
||||
if body.Seq == 0 {
|
||||
if body.Name == HandshakeMsg{
|
||||
h := Handshake{}
|
||||
mapstructure.Decode(body.Msg, &h)
|
||||
slog.Info("client 收到握手协议", "data", string(data))
|
||||
if h.Key != ""{
|
||||
this.SetProperty("secretKey", h.Key)
|
||||
}else{
|
||||
this.RemoveProperty("secretKey")
|
||||
}
|
||||
this.handshake = true
|
||||
this.handshakeChan <- true
|
||||
}else{
|
||||
//推送,需要推送到指定的代理连接
|
||||
if this.onPush != nil{
|
||||
this.onPush(this, body)
|
||||
}else{
|
||||
slog.Warn("clientconn not deal push")
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.syncLock.RLock()
|
||||
s, ok := this.syncCtxs[body.Seq]
|
||||
this.syncLock.RUnlock()
|
||||
if ok {
|
||||
s.outChan <- body
|
||||
}else{
|
||||
slog.Warn("seq not found sync",
|
||||
"seq", body.Seq,
|
||||
"msgName", body.Name)
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
slog.Error("wsReadLoop Unmarshal error", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
this.Close()
|
||||
}
|
||||
|
||||
|
||||
func (this *ClientConn) write(msg interface{}) error{
|
||||
data, err := util.Marshal(msg)
|
||||
if err == nil {
|
||||
if secretKey, err:= this.GetProperty("secretKey"); err == nil {
|
||||
key := secretKey.(string)
|
||||
slog.Info("secretKey", "secretKey", key)
|
||||
data, _ = util.AesCBCEncrypt(data, []byte(key), []byte(key), openssl.ZEROS_PADDING)
|
||||
}
|
||||
}else {
|
||||
slog.Error("wsWriteLoop Marshal body error", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if data, err := util.Zip(data); err == nil{
|
||||
if err := this.wsSocket.WriteMessage(websocket.BinaryMessage, data); err != nil {
|
||||
this.Close()
|
||||
return err
|
||||
}
|
||||
}else{
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ClientConn) Close() {
|
||||
this.wsSocket.Close()
|
||||
if !this.isClosed {
|
||||
this.isClosed = true
|
||||
if this.onClose != nil{
|
||||
this.onClose(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//设置链接属性
|
||||
func (this *ClientConn) SetProperty(key string, value interface{}) {
|
||||
this.propertyLock.Lock()
|
||||
defer this.propertyLock.Unlock()
|
||||
|
||||
this.property[key] = value
|
||||
}
|
||||
|
||||
//获取链接属性
|
||||
func (this *ClientConn) GetProperty(key string) (interface{}, error) {
|
||||
this.propertyLock.RLock()
|
||||
defer this.propertyLock.RUnlock()
|
||||
|
||||
if value, ok := this.property[key]; ok {
|
||||
return value, nil
|
||||
} else {
|
||||
return nil, errors.New("no property found")
|
||||
}
|
||||
}
|
||||
|
||||
//移除链接属性
|
||||
func (this *ClientConn) RemoveProperty(key string) {
|
||||
this.propertyLock.Lock()
|
||||
defer this.propertyLock.Unlock()
|
||||
|
||||
delete(this.property, key)
|
||||
}
|
||||
|
||||
func (this *ClientConn) SetOnClose(hookFunc func (*ClientConn)) {
|
||||
this.onClose = hookFunc
|
||||
}
|
||||
|
||||
func (this *ClientConn) SetOnPush(hookFunc func (*ClientConn, *RspBody)) {
|
||||
this.onPush = hookFunc
|
||||
}
|
||||
70
net/conn.go
Normal file
70
net/conn.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ReqBody struct {
|
||||
Seq int64 `json:"seq"`
|
||||
Name string `json:"name"`
|
||||
Msg interface{} `json:"msg"`
|
||||
Proxy string `json:"proxy"`
|
||||
}
|
||||
|
||||
type RspBody struct {
|
||||
Seq int64 `json:"seq"`
|
||||
Name string `json:"name"`
|
||||
Code int `json:"code"`
|
||||
Msg interface{} `json:"msg"`
|
||||
}
|
||||
|
||||
type WsMsgReq struct {
|
||||
Body *ReqBody
|
||||
Conn WSConn
|
||||
}
|
||||
|
||||
type WsMsgRsp struct {
|
||||
Body* RspBody
|
||||
}
|
||||
|
||||
const HandshakeMsg = "handshake"
|
||||
const HeartbeatMsg = "heartbeat"
|
||||
|
||||
type Handshake struct {
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
type Heartbeat struct {
|
||||
CTime int64 `json:"ctime"`
|
||||
STime int64 `json:"stime"`
|
||||
}
|
||||
|
||||
type WSConn interface {
|
||||
SetProperty(key string, value interface{})
|
||||
GetProperty(key string) (interface{}, error)
|
||||
RemoveProperty(key string)
|
||||
Addr() string
|
||||
Push(name string, data interface{})
|
||||
}
|
||||
|
||||
type syncCtx struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
outChan chan *RspBody
|
||||
}
|
||||
|
||||
func newSyncCtx() *syncCtx {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
return &syncCtx{ctx: ctx, cancel: cancel, outChan: make(chan *RspBody)}
|
||||
}
|
||||
|
||||
func (this* syncCtx) wait() *RspBody{
|
||||
defer this.cancel()
|
||||
select {
|
||||
case data := <- this.outChan:
|
||||
return data
|
||||
case <-this.ctx.Done():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
202
net/connMgr.go
Normal file
202
net/connMgr.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"github.com/gorilla/websocket"
|
||||
"log/slog"
|
||||
"slgserver/server/slgserver/conn"
|
||||
"slgserver/server/slgserver/pos"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var ConnMgr = Mgr{}
|
||||
var cid int64 = 0
|
||||
|
||||
type Mgr struct {
|
||||
cm sync.RWMutex
|
||||
um sync.RWMutex
|
||||
rm sync.RWMutex
|
||||
|
||||
connCache map[int64]WSConn
|
||||
userCache map[int]WSConn
|
||||
roleCache map[int]WSConn
|
||||
}
|
||||
|
||||
func (this *Mgr) NewConn(wsSocket *websocket.Conn, needSecret bool) *ServerConn {
|
||||
this.cm.Lock()
|
||||
defer this.cm.Unlock()
|
||||
|
||||
id := atomic.AddInt64(&cid, 1)
|
||||
if this.connCache == nil {
|
||||
this.connCache = make(map[int64]WSConn)
|
||||
}
|
||||
|
||||
if this.userCache == nil {
|
||||
this.userCache = make(map[int]WSConn)
|
||||
}
|
||||
|
||||
if this.roleCache == nil {
|
||||
this.roleCache = make(map[int]WSConn)
|
||||
}
|
||||
|
||||
c := NewServerConn(wsSocket, needSecret)
|
||||
c.SetProperty("cid", id)
|
||||
this.connCache[id] = c
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (this *Mgr) UserLogin(conn WSConn, session string, uid int) {
|
||||
this.um.Lock()
|
||||
defer this.um.Unlock()
|
||||
|
||||
oldConn, ok := this.userCache[uid]
|
||||
if ok {
|
||||
if conn != oldConn {
|
||||
slog.Warn("rob login",
|
||||
"uid", uid,
|
||||
"oldAddr", oldConn.Addr(),
|
||||
"newAddr", conn.Addr())
|
||||
|
||||
//这里需要通知旧端被抢登录
|
||||
oldConn.Push("robLogin", nil)
|
||||
}
|
||||
}
|
||||
this.userCache[uid] = conn
|
||||
conn.SetProperty("session", session)
|
||||
conn.SetProperty("uid", uid)
|
||||
}
|
||||
|
||||
func (this *Mgr) UserLogout(conn WSConn) {
|
||||
this.removeUser(conn)
|
||||
}
|
||||
|
||||
func (this *Mgr) removeUser(conn WSConn) {
|
||||
this.um.Lock()
|
||||
uid, err := conn.GetProperty("uid")
|
||||
if err == nil {
|
||||
//只删除自己的conn
|
||||
id := uid.(int)
|
||||
c, ok := this.userCache[id]
|
||||
if ok && c == conn {
|
||||
delete(this.userCache, id)
|
||||
}
|
||||
}
|
||||
this.um.Unlock()
|
||||
|
||||
this.rm.Lock()
|
||||
rid, err := conn.GetProperty("rid")
|
||||
if err == nil {
|
||||
//只删除自己的conn
|
||||
id := rid.(int)
|
||||
c, ok := this.roleCache[id]
|
||||
if ok && c == conn {
|
||||
delete(this.roleCache, id)
|
||||
}
|
||||
}
|
||||
this.rm.Unlock()
|
||||
|
||||
conn.RemoveProperty("session")
|
||||
conn.RemoveProperty("uid")
|
||||
conn.RemoveProperty("role")
|
||||
conn.RemoveProperty("rid")
|
||||
}
|
||||
|
||||
func (this *Mgr) RoleEnter(conn WSConn, rid int) {
|
||||
this.rm.Lock()
|
||||
defer this.rm.Unlock()
|
||||
conn.SetProperty("rid", rid)
|
||||
this.roleCache[rid] = conn
|
||||
}
|
||||
|
||||
func (this *Mgr) RemoveConn(conn WSConn) {
|
||||
this.cm.Lock()
|
||||
cid, err := conn.GetProperty("cid")
|
||||
if err == nil {
|
||||
delete(this.connCache, cid.(int64))
|
||||
conn.RemoveProperty("cid")
|
||||
}
|
||||
this.cm.Unlock()
|
||||
|
||||
this.removeUser(conn)
|
||||
}
|
||||
|
||||
func (this *Mgr) PushByRoleId(rid int, msgName string, data interface{}) bool {
|
||||
if rid <= 0 {
|
||||
return false
|
||||
}
|
||||
this.rm.Lock()
|
||||
defer this.rm.Unlock()
|
||||
conn, ok := this.roleCache[rid]
|
||||
if ok {
|
||||
conn.Push(msgName, data)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Mgr) Count() int {
|
||||
this.cm.RLock()
|
||||
defer this.cm.RUnlock()
|
||||
|
||||
return len(this.connCache)
|
||||
}
|
||||
|
||||
func (this *Mgr) Push(pushSync conn.PushSync) {
|
||||
|
||||
proto := pushSync.ToProto()
|
||||
belongRIds := pushSync.BelongToRId()
|
||||
isCellView := pushSync.IsCellView()
|
||||
x, y := pushSync.Position()
|
||||
cells := make(map[int]int)
|
||||
|
||||
//推送给开始位置
|
||||
if isCellView {
|
||||
cellRIds := pos.RPMgr.GetCellRoleIds(x, y, 8, 6)
|
||||
for _, rid := range cellRIds {
|
||||
//是否能出现在视野
|
||||
if can := pushSync.IsCanView(rid, x, y); can {
|
||||
this.PushByRoleId(rid, pushSync.PushMsgName(), proto)
|
||||
cells[rid] = rid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//推送给目标位置
|
||||
tx, ty := pushSync.TPosition()
|
||||
if tx >= 0 && ty >= 0 {
|
||||
var cellRIds []int
|
||||
if isCellView {
|
||||
cellRIds = pos.RPMgr.GetCellRoleIds(tx, ty, 8, 6)
|
||||
} else {
|
||||
cellRIds = pos.RPMgr.GetCellRoleIds(tx, ty, 0, 0)
|
||||
}
|
||||
|
||||
for _, rid := range cellRIds {
|
||||
if _, ok := cells[rid]; !ok {
|
||||
if can := pushSync.IsCanView(rid, tx, ty); can {
|
||||
this.PushByRoleId(rid, pushSync.PushMsgName(), proto)
|
||||
cells[rid] = rid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//推送给自己
|
||||
for _, rid := range belongRIds {
|
||||
if _, ok := cells[rid]; !ok {
|
||||
this.PushByRoleId(rid, pushSync.PushMsgName(), proto)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *Mgr) pushAll(msgName string, data interface{}) {
|
||||
|
||||
this.rm.Lock()
|
||||
defer this.rm.Unlock()
|
||||
for _, conn := range this.roleCache {
|
||||
conn.Push(msgName, data)
|
||||
}
|
||||
}
|
||||
68
net/proxyClient.go
Normal file
68
net/proxyClient.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/gorilla/websocket"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ProxyClient struct {
|
||||
proxy string
|
||||
conn *ClientConn
|
||||
}
|
||||
|
||||
func (this*ProxyClient) Connect() error {
|
||||
var dialer = websocket.Dialer{
|
||||
Subprotocols: []string{"p1", "p2"},
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
HandshakeTimeout: 30 * time.Second,
|
||||
}
|
||||
ws, _, err := dialer.Dial(this.proxy, nil)
|
||||
if err == nil{
|
||||
this.conn = NewClientConn(ws)
|
||||
if this.conn.Start() == false{
|
||||
return errors.New("handshake fail")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (this*ProxyClient) Send(msgName string, msg interface{}) (*RspBody, error){
|
||||
if this.conn != nil {
|
||||
return this.conn.Send(msgName, msg), nil
|
||||
}
|
||||
return nil, errors.New("conn not found")
|
||||
}
|
||||
|
||||
|
||||
func (this *ProxyClient) SetOnPush(hookFunc func (*ClientConn, *RspBody)) {
|
||||
if this.conn != nil {
|
||||
this.conn.SetOnPush(hookFunc)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ProxyClient) SetOnClose(hookFunc func (*ClientConn)) {
|
||||
if this.conn != nil {
|
||||
this.conn.SetOnClose(hookFunc)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ProxyClient) SetProperty(key string, value interface{}) {
|
||||
if this.conn != nil {
|
||||
this.conn.SetProperty(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ProxyClient) Close() {
|
||||
if this.conn != nil {
|
||||
this.conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func NewProxyClient(proxy string) *ProxyClient {
|
||||
return & ProxyClient{
|
||||
proxy: proxy,
|
||||
}
|
||||
}
|
||||
|
||||
95
net/router.go
Normal file
95
net/router.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type HandlerFunc func(req *WsMsgReq, rsp *WsMsgRsp)
|
||||
type MiddlewareFunc func(HandlerFunc) HandlerFunc
|
||||
|
||||
type Group struct {
|
||||
prefix string
|
||||
hMap map[string]HandlerFunc
|
||||
hMapMidd map[string][]MiddlewareFunc
|
||||
middleware []MiddlewareFunc
|
||||
}
|
||||
|
||||
func (this *Group) AddRouter(name string, handlerFunc HandlerFunc, middleware ...MiddlewareFunc) {
|
||||
this.hMap[name] = handlerFunc
|
||||
this.hMapMidd[name] = middleware
|
||||
}
|
||||
|
||||
func (this *Group) Use(middleware ...MiddlewareFunc) *Group {
|
||||
this.middleware = append(this.middleware, middleware...)
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *Group) applyMiddleware(name string) HandlerFunc {
|
||||
|
||||
h, ok := this.hMap[name]
|
||||
if !ok {
|
||||
//通配符
|
||||
h, ok = this.hMap["*"]
|
||||
}
|
||||
|
||||
if ok {
|
||||
for i := len(this.middleware) - 1; i >= 0; i-- {
|
||||
h = this.middleware[i](h)
|
||||
}
|
||||
|
||||
for i := len(this.hMapMidd[name]) - 1; i >= 0; i-- {
|
||||
h = this.hMapMidd[name][i](h)
|
||||
}
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func (this *Group) exec(name string, req *WsMsgReq, rsp *WsMsgRsp) {
|
||||
slog.Debug("route exec", "group", this.prefix, "name", name)
|
||||
h := this.applyMiddleware(name)
|
||||
if h == nil {
|
||||
slog.Warn("Group has not",
|
||||
"msgName", req.Body.Name)
|
||||
} else {
|
||||
h(req, rsp)
|
||||
}
|
||||
if dd, err := json.Marshal(rsp.Body); err == nil {
|
||||
slog.Debug("route response", "group", this.prefix, "name", name, "size", len(dd))
|
||||
}
|
||||
}
|
||||
|
||||
type Router struct {
|
||||
groups []*Group
|
||||
}
|
||||
|
||||
func (this *Router) Group(prefix string) *Group {
|
||||
g := &Group{prefix: prefix,
|
||||
hMap: make(map[string]HandlerFunc),
|
||||
hMapMidd: make(map[string][]MiddlewareFunc),
|
||||
}
|
||||
|
||||
this.groups = append(this.groups, g)
|
||||
return g
|
||||
}
|
||||
|
||||
func (this *Router) Run(req *WsMsgReq, rsp *WsMsgRsp) {
|
||||
name := req.Body.Name
|
||||
msgName := name
|
||||
sArr := strings.Split(name, ".")
|
||||
prefix := ""
|
||||
if len(sArr) == 2 {
|
||||
prefix = sArr[0]
|
||||
msgName = sArr[1]
|
||||
}
|
||||
|
||||
for _, g := range this.groups {
|
||||
if g.prefix == prefix {
|
||||
g.exec(msgName, req, rsp)
|
||||
} else if g.prefix == "*" {
|
||||
g.exec(msgName, req, rsp)
|
||||
}
|
||||
}
|
||||
}
|
||||
137
net/server.go
Normal file
137
net/server.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gorilla/websocket"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"slgserver/config"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// http升级websocket协议的配置
|
||||
var wsUpgrader = websocket.Upgrader{
|
||||
// 允许配置的 CORS 请求
|
||||
CheckOrigin: checkOrigin,
|
||||
}
|
||||
|
||||
var allowedOrigins = loadAllowedOrigins()
|
||||
|
||||
type server struct {
|
||||
addr string
|
||||
router *Router
|
||||
needSecret bool
|
||||
beforeClose func(WSConn)
|
||||
httpServer *http.Server
|
||||
}
|
||||
|
||||
func NewServer(addr string, needSecret bool) *server {
|
||||
s := server{
|
||||
addr: addr,
|
||||
needSecret: needSecret,
|
||||
}
|
||||
return &s
|
||||
}
|
||||
|
||||
func (this *server) Router(router *Router) {
|
||||
this.router = router
|
||||
}
|
||||
|
||||
func (this *server) Start() {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", this.wsHandler)
|
||||
|
||||
this.httpServer = &http.Server{
|
||||
Addr: this.addr,
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
slog.Info("server starting", "addr", this.addr)
|
||||
|
||||
go func() {
|
||||
if err := this.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
slog.Error("server start failed", "error", err, "addr", this.addr)
|
||||
}
|
||||
}()
|
||||
|
||||
this.waitForShutdown()
|
||||
}
|
||||
|
||||
func (this *server) waitForShutdown() {
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
|
||||
slog.Info("server shutting down...")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := this.httpServer.Shutdown(ctx); err != nil {
|
||||
slog.Error("server shutdown error", "error", err)
|
||||
} else {
|
||||
slog.Info("server shutdown gracefully")
|
||||
}
|
||||
}
|
||||
|
||||
func (this *server) SetOnBeforeClose(hookFunc func(WSConn)) {
|
||||
this.beforeClose = hookFunc
|
||||
}
|
||||
|
||||
func (this *server) wsHandler(resp http.ResponseWriter, req *http.Request) {
|
||||
|
||||
wsSocket, err := wsUpgrader.Upgrade(resp, req, nil)
|
||||
if err != nil {
|
||||
slog.Warn("websocket upgrade failed", "error", err, "remote", req.RemoteAddr)
|
||||
return
|
||||
}
|
||||
|
||||
conn := ConnMgr.NewConn(wsSocket, this.needSecret)
|
||||
slog.Info("client connect", "addr", wsSocket.RemoteAddr().String())
|
||||
|
||||
conn.SetRouter(this.router)
|
||||
conn.SetOnClose(ConnMgr.RemoveConn)
|
||||
conn.SetOnBeforeClose(this.beforeClose)
|
||||
conn.Start()
|
||||
conn.Handshake()
|
||||
|
||||
}
|
||||
|
||||
func checkOrigin(r *http.Request) bool {
|
||||
if len(allowedOrigins) == 0 {
|
||||
return true
|
||||
}
|
||||
origin := strings.ToLower(strings.TrimSpace(r.Header.Get("Origin")))
|
||||
if origin == "" {
|
||||
return true
|
||||
}
|
||||
if _, ok := allowedOrigins[origin]; ok {
|
||||
return true
|
||||
}
|
||||
slog.Warn("origin not allowed", "origin", origin)
|
||||
return false
|
||||
}
|
||||
|
||||
func loadAllowedOrigins() map[string]struct{} {
|
||||
origins := config.GetString("server.allowed_origins", "")
|
||||
if origins == "" {
|
||||
return nil
|
||||
}
|
||||
originMap := make(map[string]struct{})
|
||||
items := strings.Split(origins, ",")
|
||||
for _, item := range items {
|
||||
val := strings.ToLower(strings.TrimSpace(item))
|
||||
if val == "" {
|
||||
continue
|
||||
}
|
||||
if val == "*" {
|
||||
return nil
|
||||
}
|
||||
originMap[val] = struct{}{}
|
||||
}
|
||||
return originMap
|
||||
}
|
||||
287
net/serverconn.go
Normal file
287
net/serverconn.go
Normal file
@@ -0,0 +1,287 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"slgserver/util"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-think/openssl"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// 客户端连接
|
||||
type ServerConn struct {
|
||||
wsSocket *websocket.Conn // 底层websocket
|
||||
outChan chan *WsMsgRsp // 写队列
|
||||
isClosed bool
|
||||
needSecret bool
|
||||
Seq int64
|
||||
router *Router
|
||||
beforeClose func(conn WSConn)
|
||||
onClose func(conn WSConn)
|
||||
//链接属性
|
||||
property map[string]interface{}
|
||||
//保护链接属性修改的锁
|
||||
propertyLock sync.RWMutex
|
||||
closeChan chan struct{}
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func NewServerConn(wsSocket *websocket.Conn, needSecret bool) *ServerConn {
|
||||
conn := &ServerConn{
|
||||
wsSocket: wsSocket,
|
||||
outChan: make(chan *WsMsgRsp, 1000),
|
||||
isClosed: false,
|
||||
property: make(map[string]interface{}),
|
||||
needSecret: needSecret,
|
||||
Seq: 0,
|
||||
closeChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
return conn
|
||||
}
|
||||
|
||||
// 开启异步
|
||||
func (this *ServerConn) Start() {
|
||||
go this.wsReadLoop()
|
||||
go this.wsWriteLoop()
|
||||
}
|
||||
|
||||
func (this *ServerConn) Addr() string {
|
||||
return this.wsSocket.RemoteAddr().String()
|
||||
}
|
||||
|
||||
func (this *ServerConn) Push(name string, data interface{}) {
|
||||
rsp := &WsMsgRsp{Body: &RspBody{Name: name, Msg: data, Seq: 0}}
|
||||
this.enqueue(rsp)
|
||||
}
|
||||
|
||||
func (this *ServerConn) Send(name string, data interface{}) {
|
||||
this.Seq += 1
|
||||
rsp := &WsMsgRsp{Body: &RspBody{Name: name, Msg: data, Seq: this.Seq}}
|
||||
this.enqueue(rsp)
|
||||
}
|
||||
|
||||
func (this *ServerConn) wsReadLoop() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
e := fmt.Sprintf("%v", err)
|
||||
slog.Error("wsReadLoop error", "err", e)
|
||||
this.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-this.closeChan:
|
||||
return
|
||||
default:
|
||||
}
|
||||
// 读一个message
|
||||
_, data, err := this.wsSocket.ReadMessage()
|
||||
slog.Debug("ws read message", "size", len(data))
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
data, err = util.UnZip(data)
|
||||
if err != nil {
|
||||
slog.Error("wsReadLoop UnZip error", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
body := &ReqBody{}
|
||||
if this.needSecret {
|
||||
//检测是否有加密,没有加密发起Handshake
|
||||
if secretKey, err := this.GetProperty("secretKey"); err == nil {
|
||||
key := secretKey.(string)
|
||||
d, err := util.AesCBCDecrypt(data, []byte(key), []byte(key), openssl.ZEROS_PADDING)
|
||||
if err != nil {
|
||||
slog.Error("AesDecrypt error", "error", err)
|
||||
this.Handshake()
|
||||
} else {
|
||||
data = d
|
||||
}
|
||||
} else {
|
||||
slog.Info("secretKey not found client need handshake", "error", err)
|
||||
this.Handshake()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := util.Unmarshal(data, body); err == nil {
|
||||
req := &WsMsgReq{Conn: this, Body: body}
|
||||
rsp := &WsMsgRsp{Body: &RspBody{Name: body.Name, Seq: req.Body.Seq}}
|
||||
|
||||
if req.Body.Name == HeartbeatMsg {
|
||||
h := &Heartbeat{}
|
||||
mapstructure.Decode(body.Msg, h)
|
||||
h.STime = time.Now().UnixNano() / 1e6
|
||||
rsp.Body.Msg = h
|
||||
} else {
|
||||
if this.router != nil {
|
||||
this.router.Run(req, rsp)
|
||||
}
|
||||
}
|
||||
this.outChan <- rsp
|
||||
} else {
|
||||
slog.Error("wsReadLoop Unmarshal error", "error", err)
|
||||
this.Handshake()
|
||||
}
|
||||
}
|
||||
|
||||
this.Close()
|
||||
}
|
||||
|
||||
func (this *ServerConn) wsWriteLoop() {
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
slog.Error("wsWriteLoop error")
|
||||
this.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-this.closeChan:
|
||||
return
|
||||
case msg := <-this.outChan:
|
||||
if msg == nil {
|
||||
continue
|
||||
}
|
||||
// 写给websocket
|
||||
this.write(msg.Body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ServerConn) write(msg interface{}) error {
|
||||
data, err := util.Marshal(msg)
|
||||
slog.Debug("ws write message", "size", len(data))
|
||||
if err == nil {
|
||||
if this.needSecret {
|
||||
if secretKey, err := this.GetProperty("secretKey"); err == nil {
|
||||
key := secretKey.(string)
|
||||
data, _ = util.AesCBCEncrypt(data, []byte(key), []byte(key), openssl.ZEROS_PADDING)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
slog.Error("wsWriteLoop Marshal body error", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if data, err := util.Zip(data); err == nil {
|
||||
if err := this.wsSocket.WriteMessage(websocket.BinaryMessage, data); err != nil {
|
||||
this.Close()
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ServerConn) Close() {
|
||||
this.closeOnce.Do(func() {
|
||||
this.wsSocket.Close()
|
||||
close(this.closeChan)
|
||||
if !this.isClosed {
|
||||
this.isClosed = true
|
||||
|
||||
if this.beforeClose != nil {
|
||||
this.beforeClose(this)
|
||||
}
|
||||
|
||||
if this.onClose != nil {
|
||||
this.onClose(this)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 设置链接属性
|
||||
func (this *ServerConn) SetProperty(key string, value interface{}) {
|
||||
this.propertyLock.Lock()
|
||||
defer this.propertyLock.Unlock()
|
||||
|
||||
this.property[key] = value
|
||||
}
|
||||
|
||||
// 获取链接属性
|
||||
func (this *ServerConn) GetProperty(key string) (interface{}, error) {
|
||||
this.propertyLock.RLock()
|
||||
defer this.propertyLock.RUnlock()
|
||||
|
||||
if value, ok := this.property[key]; ok {
|
||||
return value, nil
|
||||
} else {
|
||||
return nil, errors.New("no property found")
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ServerConn) SetRouter(router *Router) {
|
||||
this.router = router
|
||||
}
|
||||
|
||||
func (this *ServerConn) SetOnClose(hookFunc func(WSConn)) {
|
||||
this.onClose = hookFunc
|
||||
}
|
||||
|
||||
func (this *ServerConn) SetOnBeforeClose(hookFunc func(WSConn)) {
|
||||
this.beforeClose = hookFunc
|
||||
}
|
||||
|
||||
// 移除链接属性
|
||||
func (this *ServerConn) RemoveProperty(key string) {
|
||||
this.propertyLock.Lock()
|
||||
defer this.propertyLock.Unlock()
|
||||
|
||||
delete(this.property, key)
|
||||
}
|
||||
|
||||
// 握手协议
|
||||
func (this *ServerConn) Handshake() {
|
||||
|
||||
secretKey := ""
|
||||
if this.needSecret {
|
||||
key, err := this.GetProperty("secretKey")
|
||||
if err == nil {
|
||||
secretKey = key.(string)
|
||||
} else {
|
||||
secretKey = util.RandSeq(16)
|
||||
}
|
||||
}
|
||||
|
||||
handshake := &Handshake{Key: secretKey}
|
||||
body := &RspBody{Name: HandshakeMsg, Msg: handshake}
|
||||
if data, err := util.Marshal(body); err == nil {
|
||||
if secretKey != "" {
|
||||
this.SetProperty("secretKey", secretKey)
|
||||
} else {
|
||||
this.RemoveProperty("secretKey")
|
||||
}
|
||||
|
||||
slog.Info("handshake secretKey",
|
||||
"secretKey", secretKey)
|
||||
|
||||
if data, err = util.Zip(data); err == nil {
|
||||
this.wsSocket.WriteMessage(websocket.BinaryMessage, data)
|
||||
}
|
||||
|
||||
} else {
|
||||
slog.Error("handshake Marshal body error", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ServerConn) enqueue(rsp *WsMsgRsp) {
|
||||
select {
|
||||
case <-this.closeChan:
|
||||
return
|
||||
case this.outChan <- rsp:
|
||||
}
|
||||
}
|
||||
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))
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user