├── .gitignore ├── .readme └── yuri.jpg ├── LICENSE ├── README.md ├── build.sh ├── conf ├── config.go └── server.conf ├── go.mod ├── go.sum ├── main_service ├── client │ ├── config.go │ ├── db_service.go │ ├── room_service.go │ ├── user_cache.go │ └── user_service.go ├── constant │ ├── chat.go │ ├── host.go │ ├── login.go │ ├── message.go │ ├── packet.go │ ├── room.go │ └── user.go ├── controller │ ├── chat.go │ ├── disconnect.go │ ├── favorate.go │ ├── host.go │ ├── login.go │ ├── newcha.go │ ├── option.go │ ├── packet.go │ ├── playerinfo.go │ ├── register.go │ ├── room.go │ ├── roomlist.go │ ├── serverlist.go │ ├── updateudp.go │ └── version.go ├── gen-go │ └── yuricore │ │ ├── room_service │ │ ├── GoUnusedProtection__.go │ │ ├── room_service-consts.go │ │ ├── room_service-remote │ │ │ └── room_service-remote.go │ │ └── room_service.go │ │ └── user_service │ │ ├── GoUnusedProtection__.go │ │ ├── user_service-consts.go │ │ ├── user_service-remote │ │ └── user_service-remote.go │ │ └── user_service.go ├── infrastructure │ ├── config │ │ └── config.go │ ├── room_service │ │ └── room_service.go │ ├── user_cache │ │ └── user_cache.go │ └── user_service │ │ └── user_service.go ├── main.go ├── model │ ├── convert │ │ └── convert.go │ ├── out │ │ ├── bag.go │ │ ├── buymenu.go │ │ ├── changeroomteam.go │ │ ├── closeresult.go │ │ ├── connecthost.go │ │ ├── cosmetics.go │ │ ├── createRoom.go │ │ ├── hoststop.go │ │ ├── inventory.go │ │ ├── itemuse.go │ │ ├── joinhost.go │ │ ├── leaveroom.go │ │ ├── lobby.go │ │ ├── loginreply.go │ │ ├── message.go │ │ ├── netinfo.go │ │ ├── newfriend.go │ │ ├── option.go │ │ ├── playjoin.go │ │ ├── roomlist.go │ │ ├── roomresult.go │ │ ├── roomsetting.go │ │ ├── serverlist.go │ │ ├── sethost.go │ │ ├── setinventory.go │ │ ├── startgame.go │ │ ├── udp.go │ │ ├── userInfo.go │ │ ├── userroomstatus.go │ │ └── userstart.go │ ├── packet │ │ ├── common.go │ │ ├── tools.go │ │ └── udp.go │ ├── server │ │ ├── channel.go │ │ ├── room.go │ │ └── server.go │ └── user │ │ ├── cache.go │ │ ├── inventory.go │ │ └── user.go ├── service │ ├── character │ │ └── new.go │ ├── chat │ │ └── chat.go │ ├── disconnect │ │ └── disconnect.go │ ├── favorate │ │ ├── setbag.go │ │ ├── setbuymenu.go │ │ └── setcosmetics.go │ ├── host │ │ ├── data.go │ │ ├── gameend.go │ │ ├── inventory.go │ │ ├── itemuse.go │ │ └── start.go │ ├── login │ │ └── login.go │ ├── option │ │ └── option.go │ ├── playerinfo │ │ └── playerinfo.go │ ├── register │ │ └── register.go │ ├── room │ │ ├── changeteam.go │ │ ├── closeresult.go │ │ ├── join.go │ │ ├── leave.go │ │ ├── new.go │ │ ├── ready.go │ │ ├── start.go │ │ └── updateSetting.go │ ├── roomlist │ │ └── roomlist.go │ ├── serverlist │ │ └── serverlist.go │ ├── udp │ │ └── udp.go │ └── version │ │ └── version.go ├── start │ ├── config.go │ ├── init.go │ ├── room_service.go │ ├── user_cache.go │ └── user_service.go ├── tcp.go └── udp.go ├── room_service ├── client │ └── room_table.go ├── controller │ ├── delroom.go │ ├── endgame.go │ ├── getroom.go │ ├── joinroom.go │ ├── leaveroom.go │ ├── newroom.go │ ├── roomlist.go │ ├── serverlist.go │ ├── sethost.go │ ├── startgame.go │ └── updateroom.go ├── infrastructure │ └── room_table │ │ └── room_table.go ├── main.go ├── service.go ├── service │ ├── delroom.go │ ├── endgame.go │ ├── getroom.go │ ├── joinroom.go │ ├── leaveroom.go │ ├── newroom.go │ ├── roomlist.go │ ├── serverlist.go │ ├── sethost.go │ ├── startgame.go │ └── updateroom.go └── start │ ├── config.go │ ├── init.go │ └── room_table.go ├── script └── bootstrap.sh ├── user_service ├── client │ ├── db_service.go │ └── userTable.go ├── controller │ ├── down.go │ ├── friends.go │ ├── login.go │ ├── nickname.go │ ├── option.go │ ├── register.go │ ├── update.go │ ├── updatecampaign.go │ ├── updateinventory.go │ └── userinfo.go ├── infrastructure │ ├── db_service │ │ └── db_service.go │ └── userTable │ │ └── userTable.go ├── main.go ├── service.go ├── service │ ├── down.go │ ├── friends.go │ ├── login.go │ ├── nickname.go │ ├── option.go │ ├── register.go │ ├── update.go │ ├── updateCosmetics.go │ ├── updatebag.go │ ├── updatebuymenu.go │ ├── updatecampaign.go │ └── userinfo.go └── start │ ├── config.go │ ├── db_service.go │ ├── init.go │ └── user_table.go ├── utils ├── bloomfilter.go ├── bytes.go ├── encode.go ├── error.go ├── ini.go ├── int.go ├── ip.go ├── kerlong.go ├── mail.go ├── password.go ├── path.go └── radom.go └── verbose ├── loger.go └── verbose.go /.gitignore: -------------------------------------------------------------------------------- 1 | output/ -------------------------------------------------------------------------------- /.readme/yuri.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MaxYang991121/YuriCore/f742403c796c6bb9d5d3bf89ecf86458a99db0c2/.readme/yuri.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## YuriCore 2 | 3 | ​ This is a partial code of server emulator 4 | 5 | ​ database: mongodb 6 | 7 | ​ you should modify your server.conf before starting the server ! 8 | 9 | ![Image](./.readme/yuri.jpg) 10 | 11 | ### 声明 12 | 13 | ​ 本项目仅用于学习交流使用,严禁用于任何商业、盗卖等行为,请24小时之内删除。 14 | 15 | ​ 请遵循GPL开源协议。 16 | 17 | ### Build 18 | 19 | Go 、MinGW 20 | 21 | ``` 22 | sh build.sh 23 | ``` 24 | 25 | ### Run 26 | 27 | ``` 28 | sh output/bootstrap.sh 29 | ``` 30 | 31 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | cd `dirname $0` && pwd 2 | cd ./main_service 3 | go build -ldflags="-w -s" -buildmode=pie -o ../output/main_service 4 | cd ../room_service 5 | go build -ldflags="-w -s" -buildmode=pie -o ../output/room_service 6 | cd ../user_service 7 | go build -ldflags="-w -s" -buildmode=pie -o ../output/user_service 8 | cd .. 9 | cp script/* output/ 10 | cp conf/server.conf output/server.conf 11 | -------------------------------------------------------------------------------- /conf/config.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/KouKouChan/YuriCore/utils" 7 | ) 8 | 9 | type CSOConf struct { 10 | MainPort uint32 11 | UserAdress string 12 | UserPort uint32 13 | RoomAdress string 14 | RoomPort uint32 15 | MaxUsers uint32 16 | UnlockAllWeapons uint32 17 | 18 | EnableDataBase uint32 19 | DBUserName string 20 | DBpassword string 21 | DBaddress string 22 | DBport string 23 | 24 | DebugLevel uint32 25 | LogFile uint32 26 | 27 | EnableRegister uint32 28 | EnableMail uint32 29 | REGPort uint32 30 | REGEmail string 31 | REGPassWord string 32 | REGSMTPaddr string 33 | 34 | CodePage string 35 | } 36 | 37 | var ( 38 | Config CSOConf 39 | ) 40 | 41 | func (conf *CSOConf) InitConf(path string) { 42 | if conf == nil { 43 | return 44 | } 45 | fmt.Printf("Reading configure file ...\n") 46 | ini_parser := utils.IniParser{} 47 | file := path 48 | if err := ini_parser.LoadIni(file); err != nil { 49 | fmt.Printf("Loading config file error[%s]\n", err.Error()) 50 | fmt.Printf("Using default data ...\n") 51 | Config.EnableDataBase = 1 52 | Config.DBUserName = "root" 53 | Config.DBpassword = "123456" 54 | Config.DBaddress = "localhost" 55 | Config.DBport = "3306" 56 | 57 | Config.MaxUsers = 0 58 | Config.UnlockAllWeapons = 1 59 | Config.MainPort = 30001 60 | Config.UserPort = 30002 61 | Config.RoomPort = 30003 62 | Config.UserAdress = "127.0.0.1" 63 | Config.RoomAdress = "127.0.0.1" 64 | 65 | Config.DebugLevel = 2 66 | Config.LogFile = 1 67 | 68 | Config.EnableRegister = 0 69 | Config.EnableMail = 0 70 | Config.CodePage = "gbk" 71 | return 72 | } 73 | 74 | Config.EnableDataBase = ini_parser.IniGetUint32("Database", "EnableDataBase") 75 | Config.DBUserName = ini_parser.IniGetString("Database", "DBUserName") 76 | Config.DBpassword = ini_parser.IniGetString("Database", "DBpassword") 77 | Config.DBaddress = ini_parser.IniGetString("Database", "DBaddress") 78 | Config.DBport = ini_parser.IniGetString("Database", "DBport") 79 | 80 | Config.MaxUsers = ini_parser.IniGetUint32("Server", "MaxUsers") 81 | if conf.MaxUsers < 0 { 82 | conf.MaxUsers = 0 83 | } 84 | Config.UnlockAllWeapons = ini_parser.IniGetUint32("Server", "UnlockAllWeapons") 85 | Config.MainPort = ini_parser.IniGetUint32("Server", "MainPort") 86 | Config.UserAdress = ini_parser.IniGetString("Server", "UserAdress") 87 | Config.UserPort = ini_parser.IniGetUint32("Server", "UserPort") 88 | Config.RoomAdress = ini_parser.IniGetString("Server", "RoomAdress") 89 | Config.RoomPort = ini_parser.IniGetUint32("Server", "RoomPort") 90 | 91 | Config.DebugLevel = ini_parser.IniGetUint32("Debug", "DebugLevel") 92 | if conf.DebugLevel > 2 || conf.DebugLevel < 0 { 93 | conf.DebugLevel = 2 94 | } 95 | Config.LogFile = ini_parser.IniGetUint32("Debug", "LogFile") 96 | 97 | Config.EnableRegister = ini_parser.IniGetUint32("Register", "EnableRegister") 98 | Config.EnableMail = ini_parser.IniGetUint32("Register", "EnableMail") 99 | Config.REGPort = ini_parser.IniGetUint32("Register", "REGPort") 100 | Config.REGEmail = ini_parser.IniGetString("Register", "REGEmail") 101 | Config.REGPassWord = ini_parser.IniGetString("Register", "REGPassWord") 102 | Config.REGSMTPaddr = ini_parser.IniGetString("Register", "REGSMTPaddr") 103 | 104 | Config.CodePage = ini_parser.IniGetString("Encode", "CodePage") 105 | } 106 | -------------------------------------------------------------------------------- /conf/server.conf: -------------------------------------------------------------------------------- 1 | ################################################################## 2 | # YuriCore configuration file # 3 | # # 4 | # By KouKouChan@2021.05 # 5 | # You can configure the Server here # 6 | ################################################################## 7 | [Database] 8 | #if DataBase is disabled , server will use json file as database 9 | #and you need to install Redis 10 | EnableDataBase=0 11 | 12 | #optional, your database account name 13 | DBUserName= 14 | 15 | #optional, your database account password 16 | DBpassword= 17 | 18 | #your mysql database ip address 19 | DBaddress=127.0.0.1 20 | 21 | #your database port 22 | DBport=30005 23 | 24 | [Server] 25 | #MaxUsers 0 = unlimited , MaxUsers < max(uint32) = 4294967295 26 | MaxUsers=0 27 | 28 | #Not implemented ! if UnlockAllWeapons is enabled , user will get all weapons 29 | #This does not affect previous user's weapon data in database 30 | UnlockAllWeapons=0 31 | 32 | #Warning ! You must modify the client is you want to change TCPPort 33 | #Don't change it to 27015、27005 34 | MainPort=30001 35 | 36 | UserAdress=127.0.0.1 37 | 38 | UserPort=30003 39 | 40 | RoomAdress=127.0.0.1 41 | 42 | RoomPort=30004 43 | 44 | [Debug] 45 | #level : 0~2 , 0=no debug info , 1=little , 2=more debug info 46 | DebugLevel=2 47 | 48 | #if LogFile is enabled , server will create a log file 49 | LogFile=1 50 | 51 | [Register] 52 | #1=enable,0=disable 53 | EnableRegister=1 54 | 55 | #Not implemented ! 1=enable,0=disable,if this is enabled,who want to register must have a email 56 | EnableMail=0 57 | 58 | #Not implemented ! Don't change it to 27015、27020 59 | REGPort=1314 60 | 61 | #Not implemented ! Your server email account 62 | REGEmail=1234567890@qq.com 63 | 64 | #Not implemented ! Your email smtp code from your smtp email server not password ! 65 | REGPassWord= 66 | 67 | #Not implemented ! Your smtp email server address,such as "smtp.qq.com" 68 | REGSMTPaddr=smtp.qq.com 69 | 70 | [Encode] 71 | #Your system code page,which up to your language, ZH-CN='gbk' , ZH-TW='big5' 72 | CodePage=gbk 73 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/KouKouChan/YuriCore 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/apache/thrift v0.14.1 7 | github.com/djimenez/iconv-go v0.0.0-20160305225143-8960e66bd3da 8 | github.com/smartystreets/goconvey v1.6.4 // indirect 9 | github.com/willf/bitset v1.1.11 10 | go.mongodb.org/mongo-driver v1.5.1 11 | golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc 12 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 13 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df 14 | gopkg.in/ini.v1 v1.62.0 15 | ) 16 | -------------------------------------------------------------------------------- /main_service/client/config.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "sync" 4 | 5 | type ConfigClient interface { 6 | } 7 | 8 | var ( 9 | configClient ConfigClient 10 | configOnce sync.Once 11 | ) 12 | 13 | func GetConfigClient() ConfigClient { 14 | return db 15 | } 16 | 17 | func InitConfigClient(client ConfigClient) { 18 | configOnce.Do( 19 | func() { 20 | configClient = client 21 | }, 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /main_service/client/db_service.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "sync" 4 | 5 | type DBClient interface { 6 | } 7 | 8 | var ( 9 | db DBClient 10 | DBOnce sync.Once 11 | ) 12 | 13 | func GetDBClient() DBClient { 14 | return db 15 | } 16 | 17 | func InitDBClient(client DBClient) { 18 | DBOnce.Do( 19 | func() { 20 | db = client 21 | }, 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /main_service/client/room_service.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "sync" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/server" 9 | ) 10 | 11 | type RoomClient interface { 12 | GetServiceList(ctx context.Context) ([]server.Server, error) 13 | GetRoomList(ctx context.Context, ServerIndex, ChannelIndex uint8) ([]server.Room, error) 14 | NewRoom(ctx context.Context, room *server.Room) (*server.Room, error) 15 | UpdateRoom(ctx context.Context, room *server.Room) (*server.Room, error) 16 | JoinRoom(ctx context.Context, userID uint32, roomID uint16) (*server.Room, error) 17 | LeaveRoom(ctx context.Context, userID uint32, roomID uint16) (*server.Room, error) 18 | StartGame(ctx context.Context, userID uint32, roomID uint16) (*server.Room, error) 19 | GetRoomInfo(ctx context.Context, roomID uint16) (*server.Room, error) 20 | UpdateRoomSafe(ctx context.Context, room *server.Room) (*server.Room, error) 21 | SetRoomHost(ctx context.Context, userID uint32, name string, roomID uint16) (*server.Room, error) 22 | DelRoom(ctx context.Context, roomID uint16) error 23 | EndGame(ctx context.Context, userID uint32, roomID uint16) (*server.Room, error) 24 | } 25 | 26 | var ( 27 | roomClient RoomClient 28 | roomOnce sync.Once 29 | ) 30 | 31 | func GetRoomClient() RoomClient { 32 | return roomClient 33 | } 34 | 35 | func InitRoomClient(client RoomClient) { 36 | roomOnce.Do( 37 | func() { 38 | fmt.Println("Room service connected") 39 | roomClient = client 40 | }, 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /main_service/client/user_cache.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "net" 6 | "sync" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/user" 9 | ) 10 | 11 | type UserCache interface { 12 | GetUserByID(ctx context.Context, id uint32) *user.UserCache 13 | GetUserByUserName(ctx context.Context, username string) *user.UserCache 14 | GetUserByConnection(ctx context.Context, client net.Conn) *user.UserCache 15 | GetChannelUsers(ctx context.Context, serverID, channelID uint8) []uint32 16 | DeleteUserByID(ctx context.Context, id uint32) 17 | DeleteUserByName(ctx context.Context, username string) 18 | DeleteUserByConnection(ctx context.Context, client net.Conn) 19 | SetUser(ctx context.Context, data *user.UserCache) error 20 | SetUserChannel(ctx context.Context, userID uint32, serverID, channelID uint8) error 21 | SetUserQuitChannel(ctx context.Context, userID uint32) error 22 | SetUserRoom(ctx context.Context, userID uint32, roomID uint16, team uint8) error 23 | SetUserStatus(ctx context.Context, userID uint32, status uint8) error 24 | QuitUserRoom(ctx context.Context, userID uint32) error 25 | FlushUserInventory(ctx context.Context, userID uint32, inventory *user.Inventory) error 26 | FlushUserUDP(ctx context.Context, userID uint32, portId uint16, localPort uint16, externalPort uint16, externalIPAddress, localIpAddress uint32) (uint16, error) 27 | SetUserIngame(ctx context.Context, userID uint32, ingame bool) error 28 | ResetKillNum(ctx context.Context, userID uint32) error 29 | ResetDeadNum(ctx context.Context, userID uint32) error 30 | ResetAssistNum(ctx context.Context, userID uint32) error 31 | GetChannelNoRoomUsers(ctx context.Context, serverID, channelID uint8) []uint32 32 | FlushUserRoomData(ctx context.Context, userID uint32, data []byte) error 33 | SetNickname(ctx context.Context, userID uint32, nickname string) error 34 | } 35 | 36 | var ( 37 | userCacheClient UserCache 38 | userCacheOnce sync.Once 39 | ) 40 | 41 | func GetUserCacheClient() UserCache { 42 | return userCacheClient 43 | } 44 | 45 | func InitUserCacheClient(client UserCache) { 46 | userCacheOnce.Do( 47 | func() { 48 | userCacheClient = client 49 | }, 50 | ) 51 | } 52 | -------------------------------------------------------------------------------- /main_service/client/user_service.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "sync" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/user" 9 | ) 10 | 11 | type UserClient interface { 12 | Login(ctx context.Context, username, password string) (*user.UserInfo, int8) 13 | Register(ctx context.Context, username, password string) (bool, error) 14 | GetUserInfo(ctx context.Context, userID uint32) (*user.UserInfo, error) 15 | UserDown(ctx context.Context, userID uint32) (bool, error) 16 | GetUserFriends(ctx context.Context, userID uint32) ([]user.UserInfo, error) 17 | AddUserPoints(ctx context.Context, userID, add uint32) (uint32, error) 18 | AddUserCash(ctx context.Context, userID, add uint32) (uint32, error) 19 | UserPlayedGame(ctx context.Context, userID, IsWin, Kills, Deaths, HeadShots uint32) (*user.UserInfo, error) 20 | UserPayPoints(ctx context.Context, userID, used uint32) (uint32, error) 21 | UserPayCash(ctx context.Context, userID, used uint32) (uint32, error) 22 | UserAddItem(ctx context.Context, userID, item uint32) (*user.UserInfo, error) 23 | UserAddFriend(ctx context.Context, userID, friendID uint32) (*user.UserInfo, error) 24 | UpdateBag(ctx context.Context, UserID uint32, BagID uint16, Slot uint8, ItemID uint16) (*user.UserInfo, error) 25 | UpdateBuymenu(ctx context.Context, UserID uint32, BuymenuID uint16, Slot uint8, ItemID uint16) (*user.UserInfo, error) 26 | UpdateCosmetics(ctx context.Context, UserID uint32, CosmeticsID uint8, cosmetics *user.UserCosmetics) (*user.UserInfo, error) 27 | UpdateCampaign(ctx context.Context, UserID uint32, CampaignID uint8) (*user.UserInfo, error) 28 | UpdateOptions(ctx context.Context, UserID uint32, options []byte) (*user.UserInfo, error) 29 | UpdateNickname(ctx context.Context, UserID uint32, nickname string) (*user.UserInfo, error) 30 | } 31 | 32 | var ( 33 | userClient UserClient 34 | userOnce sync.Once 35 | ) 36 | 37 | func GetUserClient() UserClient { 38 | return userClient 39 | } 40 | 41 | func InitUserClient(client UserClient) { 42 | userOnce.Do( 43 | func() { 44 | fmt.Println("User service connected") 45 | userClient = client 46 | }, 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /main_service/constant/chat.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( 4 | MessageTypeChannel = 1 5 | MessageTypeRoom = 2 6 | ) 7 | -------------------------------------------------------------------------------- /main_service/constant/host.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( 4 | OUTStartRoom = 0 5 | OUTJoinHost = 1 6 | OUTGameData = 2 7 | OUTHostStop = 3 8 | OUTConnectHost = 5 9 | OUTItemUsing = 100 10 | OUTSetInventory = 101 11 | LeaveResultWindow = 4 12 | ) 13 | -------------------------------------------------------------------------------- /main_service/constant/login.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( 4 | Login_Success = 0 5 | Login_RPC_ERROR = 1 6 | Login_Already = 2 7 | Login_NULL_Resp = 3 8 | Login_Wrong_Info = 4 9 | Login_DB_ERROR = 5 10 | Login_Not_Registed = 6 11 | Login_Wrong_PASSWORD = 7 12 | ) 13 | -------------------------------------------------------------------------------- /main_service/constant/message.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( 4 | ChatChannel = 1 5 | ChatRoom = 2 6 | MessageDialogBox = 10 7 | 8 | ReplyYes = "S_REPLY_YES" 9 | CSO_AuthReply_BlockedIP = "您的IP已被屏蔽" 10 | CSO_AuthReply_ServerFailed = "登录失败,请稍候再试。" 11 | CSO_AuthReply_Already = "该账号目前已有人登录,将尝试踢出该玩家。" 12 | CSO_AuthReply_Already_Failed_NotFound = "尝试踢出失败,找不到该玩家数据。" 13 | CSO_AuthReply_Already_Failed = "尝试踢出失败。" 14 | CSO_AuthReply_Not_Registed = "该账号不存在。" 15 | CSO_AuthReply_Wrong = "账号密码错误,请重新输入。" 16 | CSO_NewCharacter_Wrong = "昵称错误,请重新输入。" 17 | CSO_NewCharacter_Failed = "昵称修改失败,可能是昵称有其他人注册,请重新输入。" 18 | CSO_Register_ServerFailed = "注册失败,请稍候再试。" 19 | CSO_Register_Success = "注册成功。" 20 | CSO_Register_Failed = "注册失败。" 21 | CSO_Warning_ROOM_JOIN_FAILED_INVALID_PASSWD = "密码错误无法进入房间" 22 | ) 23 | -------------------------------------------------------------------------------- /main_service/constant/packet.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | import "math" 4 | 5 | const ( 6 | HeaderLen = 4 7 | MINSEQUENCE = 0 8 | MAXSEQUENCE = math.MaxUint8 9 | 10 | PacketTypeVersion = 0 11 | PacketTypeReply = 1 12 | PacketTypeNewCharacter = 2 13 | PacketTypeLogin = 3 14 | PacketTypeServerList = 5 15 | PacketTypeCharacter = 6 16 | PacketTypeRequestRoomList = 7 17 | PacketTypeRequestChannels = 10 18 | PacketTypeRoom = 65 19 | PacketTypeChat = 67 20 | PacketTypeHost = 68 21 | PacketTypePlayerInfo = 69 22 | PacketTypeUdp = 70 23 | PacketTypeShop = 72 24 | PacketTypeBan = 74 25 | PacketTypeOption = 76 26 | PacketTypeFavorite = 77 27 | PacketTypeUseItem = 78 28 | PacketTypeQuickJoin = 80 29 | PacketTypeReport = 83 30 | PacketTypeSignature = 85 31 | PacketTypeQuickStart = 86 32 | PacketTypeAutomatch = 88 33 | PacketTypeFriend = 89 34 | PacketTypeUnlock = 90 35 | PacketTypeMail = 91 36 | PacketTypeGZ = 95 37 | PacketTypeAchievement = 96 38 | PacketTypeSupply = 102 39 | PacketTypeDisassemble = 104 40 | PacketTypeConfigInfo = 106 41 | PacketTypeUserStart = 150 42 | PacketTypeRoomList = 151 43 | PacketTypeInventory_Add = 152 44 | PacketTypeLobby = 153 45 | PacketTypeInventory_Create = 154 46 | PacketTypeUserInfo = 157 47 | PacketTypeRegister = 163 48 | 49 | UdpPacketSignature = 87 50 | UDPTypeClient = 0 51 | UDPTypeServer = 256 52 | UDPTypeSourceTV = 512 53 | ) 54 | -------------------------------------------------------------------------------- /main_service/constant/room.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( 4 | //房间包表示 5 | OUTCreateAndJoin = 0 6 | OUTPlayerJoin = 1 7 | OUTPlayerLeave = 2 8 | OUTSetPlayerReady = 3 9 | OUTUpdateSettings = 4 10 | OUTSetHost = 5 11 | OUTSetGameResult = 6 12 | OUTCountdown = 11 13 | OUTsetUserTeam = 13 14 | //房间status 15 | StatusWaiting = 0 16 | StatusIngame = 1 17 | ) 18 | -------------------------------------------------------------------------------- /main_service/constant/user.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( //阵营 4 | UserForceUnknown = 0 5 | UserForceTerrorist = 1 6 | UserForceCounterTerrorist = 2 7 | //user status 8 | UserNotReady = 0 9 | UserIngame = 1 10 | UserReady = 2 11 | 12 | MaxLen_UserName = 32 13 | MaxLen_Password = 64 14 | ) 15 | -------------------------------------------------------------------------------- /main_service/controller/chat.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | "strings" 8 | 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 11 | "github.com/KouKouChan/YuriCore/main_service/service/chat" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | . "github.com/KouKouChan/YuriCore/verbose" 14 | ) 15 | 16 | type ChatController interface { 17 | Handle(ctx context.Context) error 18 | } 19 | 20 | type chatControllerImpl struct { 21 | client net.Conn 22 | messageType uint8 23 | message string 24 | seq *uint8 25 | } 26 | 27 | func GetChatController(client net.Conn, p *packet.PacketData) ChatController { 28 | impl := chatControllerImpl{} 29 | 30 | impl.client = client 31 | impl.messageType = utils.ReadUint8(p.Data, &p.CurOffset) 32 | impl.message = strings.TrimSpace(string(p.Data[p.CurOffset:])) // 读取剩下的所有消息,当作用户输入 33 | p.CurOffset = len(p.Data) // offset 拉满,数据已经读完 34 | 35 | return &impl 36 | } 37 | 38 | func (c *chatControllerImpl) Handle(ctx context.Context) error { 39 | // 检查 40 | if len(c.message) == 0 { 41 | return fmt.Errorf("recived chat packet %+v with null message", c.messageType) 42 | } 43 | 44 | DebugPrintf(2, "got chat message %+v", c.message) 45 | 46 | switch c.messageType { 47 | case constant.MessageTypeChannel: 48 | return chat.GetChatInfra(c.message, c.client).ChannelHandler(ctx) 49 | case constant.MessageTypeRoom: 50 | return chat.GetChatInfra(c.message, c.client).RoomHandler(ctx) 51 | default: 52 | return fmt.Errorf("Unknown chat packet %+v", c.messageType) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /main_service/controller/disconnect.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "net" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/service/disconnect" 8 | ) 9 | 10 | type DisconnectController interface { 11 | Handle(ctx context.Context) error 12 | } 13 | 14 | type disconnectControllerImpl struct { 15 | client net.Conn 16 | } 17 | 18 | func GetDisconnectController(client net.Conn) DisconnectController { 19 | impl := disconnectControllerImpl{} 20 | 21 | impl.client = client 22 | 23 | return &impl 24 | } 25 | 26 | func (d *disconnectControllerImpl) Handle(ctx context.Context) error { 27 | return disconnect.NewDisconnectService(d.client).Handle(ctx) 28 | } 29 | -------------------------------------------------------------------------------- /main_service/controller/favorate.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 9 | "github.com/KouKouChan/YuriCore/main_service/service/favorate" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type FavorateController interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type favorateControllerImpl struct { 18 | favorateType uint8 19 | client net.Conn 20 | packet *packet.PacketData 21 | } 22 | 23 | func GetFavorateController(p *packet.PacketData, client net.Conn) FavorateController { 24 | favorate := favorateControllerImpl{} 25 | 26 | favorate.favorateType = utils.ReadUint8(p.Data, &p.CurOffset) 27 | favorate.client = client 28 | favorate.packet = p 29 | 30 | return &favorate 31 | } 32 | 33 | func (r *favorateControllerImpl) Handle(ctx context.Context) error { 34 | 35 | switch r.favorateType { 36 | case 0: // buymenu 37 | return favorate.NewSetBuymenuService(r.packet, r.client).Handle(ctx) 38 | case 1: // Cosmetics 39 | return favorate.NewSetCosmeticsService(r.packet, r.client).Handle(ctx) 40 | case 2: // bag 41 | return favorate.NewSetBagService(r.packet, r.client).Handle(ctx) 42 | default: 43 | return fmt.Errorf("Unknown favorate packet %+v", r.favorateType) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /main_service/controller/host.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 9 | "github.com/KouKouChan/YuriCore/main_service/service/host" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type HostController interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type hostControllerImpl struct { 18 | hostType uint8 19 | client net.Conn 20 | packet *packet.PacketData 21 | } 22 | 23 | func GetHostController(p *packet.PacketData, client net.Conn) HostController { 24 | roomlist := hostControllerImpl{} 25 | 26 | roomlist.hostType = utils.ReadUint8(p.Data, &p.CurOffset) 27 | roomlist.client = client 28 | roomlist.packet = p 29 | 30 | return &roomlist 31 | } 32 | 33 | func (h *hostControllerImpl) Handle(ctx context.Context) error { 34 | 35 | switch h.hostType { 36 | case 0: 37 | return host.NewStartService(h.client).Handle(ctx) 38 | case 1: 39 | return host.NewGameDataService(h.packet, h.client).Handle(ctx) 40 | case 5: 41 | return host.NewGameEndService(h.client).Handle(ctx) 42 | case 100: 43 | return host.NewItemUsingService(h.packet, h.client).Handle(ctx) 44 | case 101: 45 | return host.NewGetInventoryService(h.packet, h.client).Handle(ctx) 46 | default: 47 | return fmt.Errorf("Unknown host packet %+v", h.hostType) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /main_service/controller/login.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | "strings" 8 | 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/main_service/service/login" 13 | "github.com/KouKouChan/YuriCore/utils" 14 | . "github.com/KouKouChan/YuriCore/verbose" 15 | ) 16 | 17 | type LoginController interface { 18 | Handle(ctx context.Context) error 19 | } 20 | 21 | type loginControllerImpl struct { 22 | client net.Conn 23 | username string 24 | password string 25 | seq *uint8 26 | } 27 | 28 | func GetLoginController(client net.Conn, p *packet.PacketData, seq *uint8) LoginController { 29 | impl := loginControllerImpl{} 30 | 31 | impl.client = client 32 | impl.seq = seq 33 | impl.username = strings.TrimSpace(utils.ReadStringToNULL(p.Data, &p.CurOffset)) 34 | impl.password = strings.TrimSpace(utils.ReadStringToNULL(p.Data, &p.CurOffset)) 35 | p.CurOffset = len(p.Data) // offset 拉满,数据已经读完 36 | 37 | return &impl 38 | } 39 | 40 | func (l *loginControllerImpl) Handle(ctx context.Context) error { 41 | // 检查 42 | if len(l.password) == 0 || len(l.username) == 0 { 43 | out.OnSendMessage(packet.GetNextSeq(l.seq), l.client, constant.MessageDialogBox, constant.CSO_AuthReply_Wrong) 44 | return errors.New("null username or password") 45 | } 46 | 47 | DebugPrintf(2, "got login message %+v %+v", l.username, l.password) 48 | 49 | return login.GetLoginServiceImpl(l.username, l.password, l.client, l.seq).Handle(ctx) 50 | } 51 | -------------------------------------------------------------------------------- /main_service/controller/newcha.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | "strings" 8 | 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/main_service/service/character" 13 | "github.com/KouKouChan/YuriCore/utils" 14 | . "github.com/KouKouChan/YuriCore/verbose" 15 | ) 16 | 17 | type NewCharacterController interface { 18 | Handle(ctx context.Context) error 19 | } 20 | 21 | type newCharacterControllerImpl struct { 22 | client net.Conn 23 | nickname string 24 | seq *uint8 25 | } 26 | 27 | func GetNewCharacter(client net.Conn, p *packet.PacketData, seq *uint8) NewCharacterController { 28 | impl := newCharacterControllerImpl{} 29 | 30 | impl.client = client 31 | impl.nickname = strings.TrimSpace(utils.ReadStringToNULL(p.Data, &p.CurOffset)) 32 | impl.seq = seq 33 | p.CurOffset = len(p.Data) // offset 拉满,数据已经读完 34 | 35 | return &impl 36 | } 37 | 38 | func (n *newCharacterControllerImpl) Handle(ctx context.Context) error { 39 | // 检查 40 | if len(n.nickname) == 0 { 41 | out.OnSendMessage(packet.GetNextSeq(n.seq), n.client, constant.MessageDialogBox, constant.CSO_NewCharacter_Wrong) 42 | return errors.New("null nickname") 43 | } 44 | 45 | DebugPrintf(2, "got nickname message %+v %+v", n.nickname) 46 | 47 | return character.GetNewServiceImpl(n.nickname, n.client).Handle(ctx) 48 | } 49 | -------------------------------------------------------------------------------- /main_service/controller/option.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 9 | "github.com/KouKouChan/YuriCore/main_service/service/option" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type OptionController interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type optionControllerImpl struct { 18 | client net.Conn 19 | p *packet.PacketData 20 | Type uint8 21 | } 22 | 23 | func GetOptionController(p *packet.PacketData, client net.Conn) OptionController { 24 | impl := optionControllerImpl{} 25 | 26 | impl.client = client 27 | impl.Type = utils.ReadUint8(p.Data, &p.CurOffset) 28 | impl.p = p 29 | 30 | return &impl 31 | } 32 | 33 | func (o *optionControllerImpl) Handle(ctx context.Context) error { 34 | 35 | switch o.Type { 36 | case 0: 37 | return option.NewOptionService(o.p, o.client).Handle(ctx) 38 | default: 39 | return fmt.Errorf("Unknown option packet %+v", o.Type) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /main_service/controller/packet.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "errors" 5 | "net" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/constant" 8 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 9 | "github.com/KouKouChan/YuriCore/utils" 10 | "github.com/KouKouChan/YuriCore/verbose" 11 | ) 12 | 13 | type PacketController interface { 14 | GetHeadPacket(data []byte) packet.PacketHeader 15 | GetDataPacket(header packet.PacketHeader, data []byte) packet.PacketData 16 | ReadHead(client net.Conn) ([]byte, error) 17 | ReadData(client net.Conn, len uint16) ([]byte, error) 18 | } 19 | 20 | type packetControllerImpl struct { 21 | } 22 | 23 | func NewPacketController() PacketController { 24 | return &packetControllerImpl{} 25 | } 26 | 27 | func (p *packetControllerImpl) GetHeadPacket(data []byte) packet.PacketHeader { 28 | offset := 0 29 | return packet.PacketHeader{ 30 | data, 31 | utils.ReadUint8(data, &offset), 32 | utils.ReadUint16(data, &offset), 33 | } 34 | } 35 | 36 | func (p *packetControllerImpl) GetDataPacket(header packet.PacketHeader, data []byte) packet.PacketData { 37 | return packet.PacketData{ 38 | data, 39 | header.Sequence, 40 | header.Length, 41 | data[0], 42 | 1, 43 | } 44 | } 45 | 46 | func (p *packetControllerImpl) ReadHead(client net.Conn) ([]byte, error) { 47 | SeqBuf := make([]byte, 1) 48 | headlen := constant.HeaderLen - 1 49 | head, curlen := make([]byte, headlen), 0 50 | for { 51 | n, err := client.Read(SeqBuf) 52 | if err != nil { 53 | return head, errors.New("read head signature failed !") 54 | } 55 | if n >= 1 && SeqBuf[0] == constant.PacketTypeSignature { 56 | break 57 | } 58 | verbose.DebugInfo(2, "Recived a illegal head sig", SeqBuf[0], "from", client.RemoteAddr().String()) 59 | } 60 | for { 61 | n, err := client.Read(head[curlen:]) 62 | 63 | if err != nil { 64 | return head, errors.New("read packet head failed !") 65 | } 66 | curlen += n 67 | if curlen >= headlen { 68 | break 69 | } 70 | } 71 | return head, nil 72 | } 73 | 74 | func (p *packetControllerImpl) ReadData(client net.Conn, len uint16) ([]byte, error) { 75 | data, curlen := make([]byte, len), 0 76 | for { 77 | n, err := client.Read(data[curlen:]) 78 | if err != nil { 79 | return data, errors.New("read packet data failed !") 80 | } 81 | curlen += n 82 | if curlen >= int(len) { 83 | break 84 | } 85 | } 86 | return data, nil 87 | } 88 | -------------------------------------------------------------------------------- /main_service/controller/playerinfo.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 9 | "github.com/KouKouChan/YuriCore/main_service/service/playerinfo" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type PlayerInfoController interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type playerInfoControllerImpl struct { 18 | playerType uint8 19 | client net.Conn 20 | packet *packet.PacketData 21 | } 22 | 23 | func GetPlayerInfoController(p *packet.PacketData, client net.Conn) PlayerInfoController { 24 | player := playerInfoControllerImpl{} 25 | 26 | player.playerType = utils.ReadUint8(p.Data, &p.CurOffset) 27 | player.client = client 28 | player.packet = p 29 | 30 | return &player 31 | } 32 | 33 | func (p *playerInfoControllerImpl) Handle(ctx context.Context) error { 34 | 35 | switch p.playerType { 36 | case 5: // campaign 37 | return playerinfo.NewUpdateCampaignService(p.packet, p.client).Handle(ctx) 38 | 39 | default: 40 | return fmt.Errorf("Unknown playerInfo packet %+v", p.playerType) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /main_service/controller/register.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | "strings" 8 | 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/main_service/service/register" 13 | "github.com/KouKouChan/YuriCore/utils" 14 | . "github.com/KouKouChan/YuriCore/verbose" 15 | ) 16 | 17 | type RegisterController interface { 18 | Handle(ctx context.Context) error 19 | } 20 | 21 | type registerControllerImpl struct { 22 | client net.Conn 23 | username string 24 | password string 25 | seq *uint8 26 | } 27 | 28 | func GetRegisterController(client net.Conn, p *packet.PacketData, seq *uint8) RegisterController { 29 | impl := registerControllerImpl{} 30 | 31 | impl.client = client 32 | impl.seq = seq 33 | impl.username = strings.TrimSpace(utils.ReadStringToNULL(p.Data, &p.CurOffset)) 34 | impl.password = strings.TrimSpace(utils.ReadStringToNULL(p.Data, &p.CurOffset)) 35 | p.CurOffset = len(p.Data) // offset 拉满,数据已经读完 36 | 37 | return &impl 38 | } 39 | 40 | func (r *registerControllerImpl) Handle(ctx context.Context) error { 41 | // 检查 42 | if len(r.password) == 0 || len(r.username) == 0 { 43 | out.OnSendMessage(packet.GetNextSeq(r.seq), r.client, constant.MessageDialogBox, constant.CSO_AuthReply_Wrong) 44 | return errors.New("null username or password") 45 | } 46 | 47 | DebugPrintf(2, "got register message %+v %+v", r.username, r.password) 48 | 49 | return register.GetRegisterServiceImpl(r.username, r.password, r.client, r.seq).Handle(ctx) 50 | } 51 | -------------------------------------------------------------------------------- /main_service/controller/room.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 9 | "github.com/KouKouChan/YuriCore/main_service/service/room" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type RoomController interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type roomControllerImpl struct { 18 | roomType uint8 19 | client net.Conn 20 | packet *packet.PacketData 21 | } 22 | 23 | func GetRoomController(p *packet.PacketData, client net.Conn) RoomController { 24 | roomlist := roomControllerImpl{} 25 | 26 | roomlist.roomType = utils.ReadUint8(p.Data, &p.CurOffset) 27 | roomlist.client = client 28 | roomlist.packet = p 29 | 30 | return &roomlist 31 | } 32 | 33 | func (r *roomControllerImpl) Handle(ctx context.Context) error { 34 | 35 | switch r.roomType { 36 | case 0: 37 | return room.NewCreateRoomService(r.packet, r.client).Handle(ctx) 38 | case 1: 39 | return room.NewJoinRoomService(r.packet, r.client).Handle(ctx) 40 | case 2: 41 | return room.NewLeaveRoomService(r.client).Handle(ctx) 42 | case 3: 43 | return room.NewReadyService(r.packet, r.client).Handle(ctx) 44 | case 4: 45 | return room.NewStartService(r.client).Handle(ctx) 46 | case 5: 47 | return room.NewUpdateRoomService(r.packet, r.client).Handle(ctx) 48 | case 6: 49 | return room.NewCloseResultService(r.client).Handle(ctx) 50 | case 17: 51 | return room.NewChangeTeamService(r.packet, r.client).Handle(ctx) 52 | default: 53 | return fmt.Errorf("Unknown room packet %+v", r.roomType) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /main_service/controller/roomlist.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 9 | "github.com/KouKouChan/YuriCore/main_service/service/roomlist" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type RoomListController interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type roomListControllerImpl struct { 18 | serverIndex uint8 19 | channelIndex uint8 20 | client net.Conn 21 | } 22 | 23 | func GetRoomListController(p *packet.PacketData, client net.Conn) RoomListController { 24 | roomlist := roomListControllerImpl{} 25 | 26 | roomlist.serverIndex = utils.ReadUint8(p.Data, &p.CurOffset) 27 | roomlist.channelIndex = utils.ReadUint8(p.Data, &p.CurOffset) 28 | roomlist.client = client 29 | 30 | return &roomlist 31 | } 32 | 33 | func (r *roomListControllerImpl) Handle(ctx context.Context) error { 34 | if r.channelIndex == 0 || r.serverIndex == 0 { 35 | return errors.New("wrong channelID or serverID") 36 | } 37 | 38 | return roomlist.NewRoomListService(r.serverIndex, r.channelIndex, r.client).Handler(ctx) 39 | } 40 | -------------------------------------------------------------------------------- /main_service/controller/serverlist.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "net" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/service/serverlist" 8 | ) 9 | 10 | type ServerListController interface { 11 | Handle(ctx context.Context) error 12 | } 13 | 14 | type serverListControllerImpl struct { 15 | client net.Conn 16 | } 17 | 18 | func GetServerListController(client net.Conn) ServerListController { 19 | serverlist := serverListControllerImpl{} 20 | 21 | serverlist.client = client 22 | 23 | return &serverlist 24 | } 25 | 26 | func (s *serverListControllerImpl) Handle(ctx context.Context) error { 27 | 28 | return serverlist.NewServerListService(s.client).Handler(ctx) 29 | } 30 | -------------------------------------------------------------------------------- /main_service/controller/updateudp.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/user" 7 | "github.com/KouKouChan/YuriCore/main_service/service/udp" 8 | ) 9 | 10 | type UpdateUDPController interface { 11 | Handle(ctx context.Context) (uint16, error) 12 | } 13 | 14 | type updateUDPControllerImpl struct { 15 | portId uint16 16 | localPort uint16 17 | externalPort uint16 18 | externalIPAddress uint32 19 | localIpAddress uint32 20 | 21 | user *user.UserCache 22 | } 23 | 24 | func GetUpdateUDPController(portId uint16, localPort uint16, externalPort uint16, externalIPAddress, localIpAddress uint32, user *user.UserCache) UpdateUDPController { 25 | update := updateUDPControllerImpl{ 26 | portId: portId, 27 | localPort: localPort, 28 | externalPort: externalPort, 29 | externalIPAddress: externalIPAddress, 30 | localIpAddress: localIpAddress, 31 | user: user, 32 | } 33 | 34 | return &update 35 | } 36 | 37 | func (r *updateUDPControllerImpl) Handle(ctx context.Context) (uint16, error) { 38 | 39 | return udp.GetUpdateUDPService(r.portId, r.localPort, r.externalPort, r.externalIPAddress, r.localIpAddress, r.user).Handle(ctx) 40 | } 41 | -------------------------------------------------------------------------------- /main_service/controller/version.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 7 | . "github.com/KouKouChan/YuriCore/verbose" 8 | ) 9 | 10 | type VersionController interface { 11 | Handle() error 12 | } 13 | 14 | type versionControllerImpl struct { 15 | info []byte 16 | client net.Conn 17 | } 18 | 19 | func GetVersionController(p *packet.PacketData, client net.Conn) VersionController { 20 | version := versionControllerImpl{} 21 | version.info = p.Data[p.CurOffset:] 22 | version.client = client 23 | p.CurOffset = len(p.Data) // offset 拉满,数据已经读完 24 | 25 | return &version 26 | } 27 | 28 | func (v *versionControllerImpl) Handle() error { 29 | DebugPrintf(2, "Recived version info %+v from %+v", v.info, v.client.RemoteAddr().String()) 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /main_service/gen-go/yuricore/room_service/GoUnusedProtection__.go: -------------------------------------------------------------------------------- 1 | // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. 2 | 3 | package room_service 4 | 5 | var GoUnusedProtection__ int; 6 | 7 | -------------------------------------------------------------------------------- /main_service/gen-go/yuricore/room_service/room_service-consts.go: -------------------------------------------------------------------------------- 1 | // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. 2 | 3 | package room_service 4 | 5 | import( 6 | "bytes" 7 | "context" 8 | "fmt" 9 | "time" 10 | "github.com/apache/thrift/lib/go/thrift" 11 | ) 12 | 13 | // (needed to ensure safety because of naive import list construction.) 14 | var _ = thrift.ZERO 15 | var _ = fmt.Printf 16 | var _ = context.Background 17 | var _ = time.Now 18 | var _ = bytes.Equal 19 | 20 | 21 | func init() { 22 | } 23 | 24 | -------------------------------------------------------------------------------- /main_service/gen-go/yuricore/user_service/GoUnusedProtection__.go: -------------------------------------------------------------------------------- 1 | // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. 2 | 3 | package user_service 4 | 5 | var GoUnusedProtection__ int; 6 | 7 | -------------------------------------------------------------------------------- /main_service/gen-go/yuricore/user_service/user_service-consts.go: -------------------------------------------------------------------------------- 1 | // Code generated by Thrift Compiler (0.14.1). DO NOT EDIT. 2 | 3 | package user_service 4 | 5 | import( 6 | "bytes" 7 | "context" 8 | "fmt" 9 | "time" 10 | "github.com/apache/thrift/lib/go/thrift" 11 | ) 12 | 13 | // (needed to ensure safety because of naive import list construction.) 14 | var _ = thrift.ZERO 15 | var _ = fmt.Printf 16 | var _ = context.Background 17 | var _ = time.Now 18 | var _ = bytes.Equal 19 | 20 | 21 | func init() { 22 | } 23 | 24 | -------------------------------------------------------------------------------- /main_service/infrastructure/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type ConfigImpl struct{} 4 | 5 | func NewConfigImpl() *ConfigImpl { 6 | return &ConfigImpl{} 7 | } 8 | -------------------------------------------------------------------------------- /main_service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | 9 | "github.com/KouKouChan/YuriCore/main_service/start" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | var ( 14 | // SERVERVERSION 版本号 15 | SERVERVERSION = "v1.3" 16 | ) 17 | 18 | func main() { 19 | fmt.Println("YuriCore Server", SERVERVERSION) 20 | fmt.Println("Initializing process ...") 21 | 22 | ExePath, err := utils.GetExePath() 23 | if err != nil { 24 | panic(err) 25 | } 26 | 27 | start.Init(ExePath) 28 | 29 | go initTCP() 30 | go initUDP() 31 | 32 | ch := make(chan os.Signal) 33 | defer close(ch) 34 | signal.Notify(ch, syscall.SIGINT) 35 | _ = <-ch 36 | 37 | fmt.Println("Press CTRL+C again to close server") 38 | 39 | signal.Notify(ch, syscall.SIGINT) 40 | _ = <-ch 41 | } 42 | -------------------------------------------------------------------------------- /main_service/model/out/bag.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/user" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildUserBag(bags [3]user.UserLoadout) []byte { 9 | buf := make([]byte, 256) 10 | offset := 0 11 | 12 | utils.WriteUint8(&buf, 2, &offset) 13 | utils.WriteUint16(&buf, 0, &offset) 14 | utils.WriteUint8(&buf, 0, &offset) 15 | utils.WriteUint8(&buf, uint8(len(bags)), &offset) 16 | utils.WriteUint8(&buf, 4, &offset) 17 | 18 | utils.WriteUint16(&buf, bags[0].MainWeapon, &offset) 19 | utils.WriteUint16(&buf, bags[0].SecondWeapon, &offset) 20 | utils.WriteUint16(&buf, bags[0].Knife, &offset) 21 | utils.WriteUint16(&buf, bags[0].Grenade, &offset) 22 | 23 | utils.WriteUint16(&buf, bags[1].MainWeapon, &offset) 24 | utils.WriteUint16(&buf, bags[1].SecondWeapon, &offset) 25 | utils.WriteUint16(&buf, bags[1].Knife, &offset) 26 | utils.WriteUint16(&buf, bags[1].Grenade, &offset) 27 | 28 | utils.WriteUint16(&buf, bags[2].MainWeapon, &offset) 29 | utils.WriteUint16(&buf, bags[2].SecondWeapon, &offset) 30 | utils.WriteUint16(&buf, bags[2].Knife, &offset) 31 | utils.WriteUint16(&buf, bags[2].Grenade, &offset) 32 | return buf[:offset] 33 | } 34 | -------------------------------------------------------------------------------- /main_service/model/out/buymenu.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/user" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildUserBuymenu(buymenu *user.UserBuyMenu) []byte { 9 | buf := make([]byte, 512) 10 | offset := 0 11 | 12 | utils.WriteUint8(&buf, 0, &offset) 13 | 14 | utils.WriteUint8(&buf, 0, &offset) 15 | for i := range buymenu.PistolsTR { 16 | utils.WriteUint16(&buf, buymenu.PistolsTR[i], &offset) 17 | } 18 | 19 | utils.WriteUint8(&buf, 1, &offset) 20 | for i := range buymenu.PistolsTR { 21 | utils.WriteUint16(&buf, buymenu.ShotgunsTR[i], &offset) 22 | } 23 | 24 | utils.WriteUint8(&buf, 2, &offset) 25 | for i := range buymenu.PistolsTR { 26 | utils.WriteUint16(&buf, buymenu.SmgsTR[i], &offset) 27 | } 28 | 29 | utils.WriteUint8(&buf, 3, &offset) 30 | for i := range buymenu.PistolsTR { 31 | utils.WriteUint16(&buf, buymenu.RiflesTR[i], &offset) 32 | } 33 | 34 | utils.WriteUint8(&buf, 4, &offset) 35 | for i := range buymenu.PistolsTR { 36 | utils.WriteUint16(&buf, buymenu.MachinegunsTR[i], &offset) 37 | } 38 | 39 | utils.WriteUint8(&buf, 5, &offset) 40 | for i := range buymenu.PistolsTR { 41 | utils.WriteUint16(&buf, buymenu.EquipmentTR[i], &offset) 42 | } 43 | 44 | utils.WriteUint8(&buf, 6, &offset) 45 | for i := range buymenu.PistolsTR { 46 | utils.WriteUint16(&buf, buymenu.ClassesTR[i], &offset) 47 | } 48 | 49 | utils.WriteUint8(&buf, 7, &offset) 50 | for i := range buymenu.PistolsTR { 51 | utils.WriteUint16(&buf, buymenu.PistolsCT[i], &offset) 52 | } 53 | 54 | utils.WriteUint8(&buf, 8, &offset) 55 | for i := range buymenu.PistolsTR { 56 | utils.WriteUint16(&buf, buymenu.ShotgunsCT[i], &offset) 57 | } 58 | 59 | utils.WriteUint8(&buf, 9, &offset) 60 | for i := range buymenu.PistolsTR { 61 | utils.WriteUint16(&buf, buymenu.SmgsCT[i], &offset) 62 | } 63 | 64 | utils.WriteUint8(&buf, 10, &offset) 65 | for i := range buymenu.PistolsTR { 66 | utils.WriteUint16(&buf, buymenu.RiflesCT[i], &offset) 67 | } 68 | 69 | utils.WriteUint8(&buf, 11, &offset) 70 | for i := range buymenu.PistolsTR { 71 | utils.WriteUint16(&buf, buymenu.MachinegunsCT[i], &offset) 72 | } 73 | 74 | utils.WriteUint8(&buf, 12, &offset) 75 | for i := range buymenu.PistolsTR { 76 | utils.WriteUint16(&buf, buymenu.EquipmentCT[i], &offset) 77 | } 78 | 79 | utils.WriteUint8(&buf, 13, &offset) 80 | for i := range buymenu.PistolsTR { 81 | utils.WriteUint16(&buf, buymenu.ClassesCT[i], &offset) 82 | } 83 | 84 | utils.WriteUint8(&buf, 14, &offset) 85 | for i := range buymenu.PistolsTR { 86 | utils.WriteUint16(&buf, buymenu.MeleesTR[i], &offset) 87 | } 88 | 89 | utils.WriteUint8(&buf, 15, &offset) 90 | for i := range buymenu.PistolsTR { 91 | utils.WriteUint16(&buf, buymenu.MeleesCT[i], &offset) 92 | } 93 | return buf[:offset] 94 | } 95 | -------------------------------------------------------------------------------- /main_service/model/out/changeroomteam.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildChangTeam(id uint32, team uint8) []byte { 9 | buf := make([]byte, 7) 10 | offset := 0 11 | utils.WriteUint8(&buf, constant.OUTsetUserTeam, &offset) 12 | utils.WriteUint32(&buf, id, &offset) 13 | utils.WriteUint8(&buf, team, &offset) 14 | return buf[:offset] 15 | } 16 | -------------------------------------------------------------------------------- /main_service/model/out/closeresult.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import "github.com/KouKouChan/YuriCore/main_service/constant" 4 | 5 | func BuildCloseResultWindow() []byte { 6 | buf := make([]byte, 1) 7 | buf[0] = constant.LeaveResultWindow 8 | return buf 9 | } 10 | -------------------------------------------------------------------------------- /main_service/model/out/connecthost.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildConnectHost(ip uint32, port uint16) []byte { 9 | buf := make([]byte, 8) 10 | offset := 0 11 | utils.WriteUint8(&buf, constant.OUTConnectHost, &offset) 12 | utils.WriteUint32BE(&buf, ip, &offset) 13 | utils.WriteUint16(&buf, port, &offset) 14 | return buf[:offset] 15 | } 16 | -------------------------------------------------------------------------------- /main_service/model/out/cosmetics.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/user" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildUserCosmetics(cosmetics [5]user.UserCosmetics) []byte { 9 | buf := make([]byte, 512) 10 | offset := 0 11 | 12 | utils.WriteUint8(&buf, 1, &offset) 13 | 14 | for i := range cosmetics { 15 | utils.WriteUint8(&buf, uint8(i), &offset) 16 | utils.WriteStringWithNull(&buf, []byte(cosmetics[i].CosmeticsName), &offset) 17 | utils.WriteUint16(&buf, cosmetics[i].MainWeapon, &offset) 18 | utils.WriteUint16(&buf, cosmetics[i].MainBullet, &offset) 19 | utils.WriteUint16(&buf, cosmetics[i].SecondWeapon, &offset) 20 | utils.WriteUint16(&buf, cosmetics[i].SecondBullet, &offset) 21 | utils.WriteUint16(&buf, cosmetics[i].FlashbangNum, &offset) 22 | utils.WriteUint16(&buf, cosmetics[i].GrenadeID, &offset) 23 | utils.WriteUint16(&buf, cosmetics[i].SmokeNum, &offset) 24 | utils.WriteUint16(&buf, cosmetics[i].DefuserNum, &offset) 25 | utils.WriteUint16(&buf, cosmetics[i].TelescopeNum, &offset) 26 | utils.WriteUint16(&buf, cosmetics[i].BulletproofNum, &offset) 27 | utils.WriteUint16(&buf, cosmetics[i].KnifeID, &offset) 28 | } 29 | 30 | return buf[:offset] 31 | } 32 | -------------------------------------------------------------------------------- /main_service/model/out/createRoom.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/main_service/model/server" 6 | "github.com/KouKouChan/YuriCore/main_service/model/user" 7 | "github.com/KouKouChan/YuriCore/utils" 8 | ) 9 | 10 | func BuildCreateRoom(users []*user.UserInfo, caches []*user.UserCache, room *server.Room) []byte { 11 | if len(users) != len(caches) { 12 | return []byte{} 13 | } 14 | 15 | buf := make([]byte, 128) 16 | offset := 0 17 | 18 | utils.WriteUint8(&buf, constant.OUTCreateAndJoin, &offset) 19 | utils.WriteUint32(&buf, room.HostUserID, &offset) 20 | utils.WriteUint16(&buf, room.RoomId, &offset) 21 | utils.WriteUint8(&buf, 0x01, &offset) 22 | buf = utils.BytesCombine(buf[:offset], BuildRoomSetting(room, 0xFFFFFFFF7FFFFFFF)) 23 | buf = append(buf, uint8(len(users))) 24 | for i := range users { 25 | if caches[i].UserID != users[i].UserID { 26 | continue 27 | } 28 | buf = utils.BytesCombine(buf, BuildUserNetInfo(caches[i]), BuildUserInfo(NewUserInfo(users[i]), false, 0xFFFFFFFF)) 29 | } 30 | 31 | return buf 32 | } 33 | -------------------------------------------------------------------------------- /main_service/model/out/hoststop.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildHostStop() []byte { 9 | buf := make([]byte, 1) 10 | offset := 0 11 | utils.WriteUint8(&buf, constant.OUTHostStop, &offset) 12 | 13 | return buf[:offset] 14 | } 15 | -------------------------------------------------------------------------------- /main_service/model/out/inventory.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/user" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildUserInventory(inventory *user.Inventory) []byte { 9 | buf := make([]byte, 8192) 10 | offset := 0 11 | 12 | utils.WriteUint16(&buf, uint16(len(inventory.Items)), &offset) 13 | for i := range inventory.Items { 14 | utils.WriteUint16(&buf, uint16(i), &offset) 15 | utils.WriteUint8(&buf, inventory.Items[i].Existed, &offset) // 1 = existed 16 | if inventory.Items[i].Existed == 1 { 17 | utils.WriteUint16(&buf, inventory.Items[i].Id, &offset) 18 | utils.WriteUint16(&buf, inventory.Items[i].Count, &offset) 19 | utils.WriteUint8(&buf, 1, &offset) 20 | utils.WriteUint8(&buf, 0, &offset) 21 | utils.WriteUint32(&buf, 0, &offset) 22 | utils.WriteUint32(&buf, 0, &offset) 23 | utils.WriteUint32(&buf, 0, &offset) 24 | } 25 | } 26 | 27 | return buf[:offset] 28 | } 29 | -------------------------------------------------------------------------------- /main_service/model/out/itemuse.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildHostItemUsing(userID uint32, itemID uint16, num uint8) []byte { 9 | buf := make([]byte, 32) 10 | offset := 0 11 | 12 | utils.WriteUint8(&buf, constant.OUTItemUsing, &offset) 13 | utils.WriteUint32(&buf, userID, &offset) 14 | utils.WriteUint16(&buf, itemID, &offset) 15 | utils.WriteUint8(&buf, num, &offset) 16 | 17 | return buf[:offset] 18 | } 19 | -------------------------------------------------------------------------------- /main_service/model/out/joinhost.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildJoinHost(host uint32) []byte { 9 | buf := make([]byte, 8) 10 | offset := 0 11 | utils.WriteUint8(&buf, constant.OUTJoinHost, &offset) 12 | utils.WriteUint32(&buf, host, &offset) 13 | return buf[:offset] 14 | } 15 | -------------------------------------------------------------------------------- /main_service/model/out/leaveroom.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildLeaveRoom(id uint32) []byte { 9 | buf := make([]byte, 8) 10 | offset := 0 11 | utils.WriteUint8(&buf, constant.OUTPlayerLeave, &offset) 12 | utils.WriteUint32(&buf, id, &offset) 13 | return buf[:offset] 14 | } 15 | -------------------------------------------------------------------------------- /main_service/model/out/lobby.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/user" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildLobbyReply(users []user.UserInfo) []byte { 9 | buf := make([]byte, 3) 10 | offset := 0 11 | 12 | utils.WriteUint8(&buf, 0, &offset) 13 | utils.WriteUint16(&buf, uint16(len(users)), &offset) 14 | for i := range users { 15 | head := make([]byte, 64) 16 | head_offset := 0 17 | utils.WriteUint32(&head, users[i].UserID, &head_offset) 18 | utils.WriteStringWithNull(&head, []byte(users[i].NickName), &head_offset) 19 | buf = utils.BytesCombine(buf, head[:head_offset]) 20 | buf = utils.BytesCombine(buf, BuildUserInfo(NewUserInfo(&users[i]), false, 0xFFFFFFFF)) 21 | } 22 | return buf 23 | } 24 | 25 | func BuildLobbyLeave(userID uint32) []byte { 26 | buf := make([]byte, 8) 27 | offset := 0 28 | 29 | utils.WriteUint8(&buf, 2, &offset) 30 | utils.WriteUint32(&buf, userID, &offset) 31 | return buf[:offset] 32 | } 33 | 34 | func BuildLobbyJoin(user *user.UserInfo) []byte { 35 | buf := make([]byte, 128) 36 | offset := 0 37 | 38 | utils.WriteUint8(&buf, 1, &offset) 39 | utils.WriteUint32(&buf, user.UserID, &offset) 40 | utils.WriteStringWithNull(&buf, []byte(user.NickName), &offset) 41 | buf = utils.BytesCombine(buf[:offset], BuildUserInfo(NewUserInfo(user), false, 0xFFFFFFFF)) 42 | return buf 43 | } 44 | -------------------------------------------------------------------------------- /main_service/model/out/loginreply.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildLoginReply() []byte { 9 | buf := make([]byte, 32) 10 | offset := 0 11 | utils.WriteUint8(&buf, 0, &offset) 12 | utils.WriteStringWithNull(&buf, []byte(constant.ReplyYes), &offset) 13 | utils.WriteUint8(&buf, 0, &offset) 14 | return buf[:offset] 15 | } 16 | 17 | func BuildNicknameReply() []byte { 18 | buf := make([]byte, 32) 19 | offset := 0 20 | utils.WriteUint8(&buf, 1, &offset) 21 | utils.WriteStringWithNull(&buf, []byte(constant.ReplyYes), &offset) 22 | utils.WriteUint8(&buf, 0, &offset) 23 | return buf[:offset] 24 | } 25 | -------------------------------------------------------------------------------- /main_service/model/out/message.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/constant" 7 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 8 | "github.com/KouKouChan/YuriCore/utils" 9 | ) 10 | 11 | func OnSendMessage(seq uint8, client net.Conn, tp uint8, msg string) { 12 | buf := make([]byte, 128) 13 | offset := 0 14 | 15 | ansi, _ := utils.Utf8ToLocal(msg) 16 | utils.WriteUint8(&buf, tp, &offset) 17 | utils.WriteStringWithNull(&buf, []byte(ansi), &offset) 18 | utils.WriteUint8(&buf, 0, &offset) 19 | 20 | packet.SendPacket(utils.BytesCombine(packet.BuildHeader(seq, constant.PacketTypeChat), buf[:offset]), client) 21 | } 22 | 23 | func BuildRoomMessage(name, message string) []byte { 24 | buf := make([]byte, 256) 25 | offset := 0 26 | utils.WriteUint8(&buf, constant.ChatRoom, &offset) 27 | utils.WriteStringWithNull(&buf, []byte(name), &offset) 28 | utils.WriteStringWithNull(&buf, []byte(message), &offset) 29 | return buf[:offset] 30 | } 31 | 32 | func BuildChannelMessage(name, message string) []byte { 33 | buf := make([]byte, 256) 34 | offset := 0 35 | utils.WriteUint8(&buf, constant.ChatChannel, &offset) 36 | utils.WriteStringWithNull(&buf, []byte(name), &offset) 37 | utils.WriteStringWithNull(&buf, []byte(message), &offset) 38 | return buf[:offset] 39 | } 40 | -------------------------------------------------------------------------------- /main_service/model/out/netinfo.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/user" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildUserNetInfo(u *user.UserCache) []byte { 9 | buf := make([]byte, 29) 10 | offset := 0 11 | utils.WriteUint32(&buf, u.UserID, &offset) 12 | utils.WriteUint8(&buf, u.CurrentTeam, &offset) 13 | utils.WriteUint8(&buf, u.Currentstatus, &offset) 14 | utils.WriteUint8(&buf, 0, &offset) // status 15 | utils.WriteUint32BE(&buf, u.NetInfo.ExternalIpAddress, &offset) //externalIpAddress 16 | utils.WriteUint16(&buf, u.NetInfo.ExternalServerPort, &offset) //externalServerPort 17 | utils.WriteUint16(&buf, u.NetInfo.ExternalClientPort, &offset) //externalClientPort 18 | utils.WriteUint32BE(&buf, u.NetInfo.LocalIpAddress, &offset) //localIpAddress 19 | utils.WriteUint16(&buf, u.NetInfo.LocalServerPort, &offset) //localServerPort 20 | utils.WriteUint16(&buf, u.NetInfo.LocalClientPort, &offset) //localClientPort 21 | return buf[:offset] 22 | } 23 | -------------------------------------------------------------------------------- /main_service/model/out/newfriend.go: -------------------------------------------------------------------------------- 1 | package out 2 | -------------------------------------------------------------------------------- /main_service/model/out/option.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/user" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildUserOptions(user *user.UserInfo) []byte { 9 | buf := make([]byte, 4096) 10 | offset := 0 11 | 12 | utils.WriteUint8(&buf, 0, &offset) 13 | utils.WriteLongString(&buf, user.Options, &offset) 14 | 15 | return buf[:offset] 16 | } 17 | -------------------------------------------------------------------------------- /main_service/model/out/playjoin.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/main_service/model/user" 6 | "github.com/KouKouChan/YuriCore/utils" 7 | ) 8 | 9 | func BuildPlayerJoin(u *user.UserCache, info *user.UserInfo) []byte { 10 | buf := make([]byte, 1) 11 | offset := 0 12 | utils.WriteUint8(&buf, constant.OUTPlayerJoin, &offset) 13 | buf = utils.BytesCombine(buf, BuildUserNetInfo(u), BuildUserInfo(NewUserInfo(info), false, 0xFFFFFFFF)) 14 | return buf 15 | } 16 | -------------------------------------------------------------------------------- /main_service/model/out/roomlist.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/server" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildRoomList(rooms []server.Room) []byte { 9 | buf := make([]byte, 3) 10 | offset := 0 11 | utils.WriteUint8(&buf, 0, &offset) 12 | utils.WriteUint16(&buf, uint16(len(rooms)), &offset) 13 | 14 | for i := range rooms { 15 | buf = utils.BytesCombine(buf, BuildRoomChannelInfo(&rooms[i], true, 0xFFFFFFFF)) 16 | } 17 | 18 | return buf 19 | } 20 | 21 | func BuildUpdateChannelRoom(room *server.Room, needID bool, flag uint32) []byte { 22 | buf := make([]byte, 1) 23 | offset := 0 24 | utils.WriteUint8(&buf, 3, &offset) 25 | buf = utils.BytesCombine(buf, BuildRoomChannelInfo(room, needID, flag)) 26 | return buf 27 | } 28 | 29 | func BuildDeleteChannelRoom(roomID uint16) []byte { 30 | buf := make([]byte, 4) 31 | offset := 0 32 | utils.WriteUint8(&buf, 2, &offset) 33 | utils.WriteUint16(&buf, roomID, &offset) 34 | return buf[:offset] 35 | } 36 | 37 | func BuildAddChannelRoom(room *server.Room, needID bool, flag uint32) []byte { 38 | buf := make([]byte, 1) 39 | offset := 0 40 | utils.WriteUint8(&buf, 1, &offset) 41 | buf = utils.BytesCombine(buf, BuildRoomChannelInfo(room, needID, flag)) 42 | return buf 43 | } 44 | 45 | func BuildRoomChannelInfo(room *server.Room, needID bool, flag uint32) []byte { 46 | buf := make([]byte, 512) 47 | offset := 0 48 | 49 | if needID { 50 | utils.WriteUint16(&buf, room.RoomId, &offset) 51 | } 52 | 53 | utils.WriteUint32(&buf, flag, &offset) 54 | 55 | if flag&0x1 != 0 { 56 | utils.WriteStringWithNull(&buf, []byte(room.RoomName), &offset) 57 | } 58 | 59 | if flag&0x2 != 0 { 60 | utils.WriteUint8(&buf, 0, &offset) 61 | } 62 | 63 | if flag&0x4 != 0 { 64 | if room.PassWd != "" { 65 | utils.WriteUint8(&buf, 1, &offset) 66 | } else { 67 | utils.WriteUint8(&buf, 0, &offset) 68 | } 69 | } 70 | 71 | if flag&0x8 != 0 { 72 | utils.WriteUint8(&buf, 0, &offset) 73 | } 74 | 75 | if flag&0x10 != 0 { 76 | utils.WriteUint8(&buf, room.GameModeID, &offset) 77 | } 78 | 79 | if flag&0x20 != 0 { 80 | utils.WriteUint8(&buf, room.MapID, &offset) 81 | } 82 | 83 | if flag&0x40 != 0 { 84 | utils.WriteUint8(&buf, uint8(len(room.Users)), &offset) 85 | } 86 | 87 | if flag&0x80 != 0 { 88 | utils.WriteUint8(&buf, room.MaxPlayers, &offset) 89 | } 90 | 91 | if flag&0x100 != 0 { 92 | utils.WriteUint8(&buf, 0, &offset) 93 | } 94 | 95 | if flag&0x200 != 0 { 96 | utils.WriteUint32(&buf, room.HostUserID, &offset) 97 | utils.WriteUint8(&buf, 0, &offset) 98 | } 99 | 100 | if flag&0x400 != 0 { 101 | utils.WriteUint8(&buf, 0, &offset) 102 | } 103 | 104 | if flag&0x800 != 0 { 105 | utils.WriteUint32(&buf, 3, &offset) 106 | utils.WriteUint16(&buf, 0, &offset) 107 | utils.WriteUint32(&buf, 3, &offset) 108 | utils.WriteUint16(&buf, 0, &offset) 109 | utils.WriteUint8(&buf, 2, &offset) 110 | } 111 | 112 | if flag&0x1000 != 0 { 113 | utils.WriteUint8(&buf, 0, &offset) 114 | } 115 | 116 | if flag&0x2000 != 0 { 117 | utils.WriteUint8(&buf, 0, &offset) 118 | } 119 | 120 | if flag&0x4000 != 0 { 121 | utils.WriteUint8(&buf, uint8(len(room.Users)), &offset) 122 | } 123 | 124 | if flag&0x8000 != 0 { 125 | utils.WriteUint8(&buf, 0, &offset) 126 | } 127 | 128 | if flag&0x10000 != 0 { 129 | utils.WriteUint8(&buf, 0, &offset) 130 | } 131 | 132 | if flag&0x20000 != 0 { 133 | utils.WriteUint16(&buf, 0, &offset) 134 | } 135 | 136 | if flag&0x40000 != 0 { 137 | utils.WriteUint8(&buf, 0, &offset) 138 | } 139 | 140 | if flag&0x80000 != 0 { 141 | utils.WriteUint8(&buf, 0, &offset) 142 | } 143 | 144 | if flag&0x100000 != 0 { 145 | utils.WriteUint8(&buf, 0, &offset) 146 | } 147 | 148 | if flag&0x200000 != 0 { 149 | utils.WriteUint8(&buf, 0, &offset) 150 | } 151 | 152 | if flag&0x400000 != 0 { 153 | utils.WriteUint8(&buf, 0, &offset) 154 | } 155 | 156 | if flag&0x800000 != 0 { 157 | utils.WriteUint8(&buf, 0, &offset) 158 | } 159 | 160 | if flag&0x1000000 != 0 { 161 | utils.WriteUint8(&buf, 0, &offset) 162 | } 163 | 164 | return buf[:offset] 165 | } 166 | -------------------------------------------------------------------------------- /main_service/model/out/roomresult.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/main_service/model/server" 6 | "github.com/KouKouChan/YuriCore/utils" 7 | ) 8 | 9 | func BuildRoomResult(room *server.Room) []byte { 10 | buf := make([]byte, 512) 11 | offset := 0 12 | utils.WriteUint8(&buf, constant.OUTSetGameResult, &offset) 13 | utils.WriteUint8(&buf, 0, &offset) 14 | utils.WriteUint8(&buf, 0, &offset) 15 | utils.WriteUint8(&buf, 0, &offset) 16 | utils.WriteUint8(&buf, 0, &offset) 17 | utils.WriteUint8(&buf, 0, &offset) 18 | utils.WriteUint8(&buf, 0, &offset) 19 | 20 | return buf[:offset] 21 | } 22 | -------------------------------------------------------------------------------- /main_service/model/out/serverlist.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/model/server" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildServerList(servers []server.Server) []byte { 9 | buf := make([]byte, 4096) 10 | offset := 0 11 | utils.WriteUint8(&buf, uint8(len(servers)), &offset) 12 | for i := range servers { 13 | utils.WriteUint8(&buf, servers[i].ServerIndex, &offset) 14 | utils.WriteUint8(&buf, servers[i].ServerStatus, &offset) 15 | utils.WriteUint8(&buf, servers[i].ServerType, &offset) 16 | ansiName, _ := utils.Utf8ToLocal(servers[i].ServerName) 17 | utils.WriteStringWithNull(&buf, []byte(ansiName), &offset) 18 | utils.WriteUint8(&buf, uint8(len(servers[i].Channels)), &offset) 19 | for j := range servers[i].Channels { 20 | utils.WriteUint8(&buf, servers[i].Channels[j].ChannelIndex, &offset) 21 | ansiName, _ := utils.Utf8ToLocal(servers[i].Channels[j].ChannelName) 22 | utils.WriteStringWithNull(&buf, []byte(ansiName), &offset) 23 | utils.WriteUint16(&buf, 0x00, &offset) 24 | } 25 | } 26 | return buf[:offset] 27 | } 28 | -------------------------------------------------------------------------------- /main_service/model/out/sethost.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildSetHost(id uint32, isHost uint8) []byte { 9 | buf := make([]byte, 6) 10 | offset := 0 11 | utils.WriteUint8(&buf, constant.OUTSetHost, &offset) 12 | utils.WriteUint32(&buf, id, &offset) 13 | utils.WriteUint8(&buf, isHost, &offset) 14 | return buf[:offset] 15 | } 16 | -------------------------------------------------------------------------------- /main_service/model/out/setinventory.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/main_service/model/user" 6 | "github.com/KouKouChan/YuriCore/utils" 7 | ) 8 | 9 | func BuildSetUserInventory(u *user.UserCache) []byte { 10 | buf := make([]byte, 8+8*len(u.UserInventory.Items)) 11 | offset := 0 12 | utils.WriteUint8(&buf, constant.OUTSetInventory, &offset) 13 | utils.WriteUint32(&buf, u.UserID, &offset) 14 | utils.WriteUint16(&buf, uint16(len(u.UserInventory.Items)), &offset) 15 | for _, v := range u.UserInventory.Items { 16 | utils.WriteUint16(&buf, v.Id, &offset) 17 | utils.WriteUint16(&buf, v.Count, &offset) 18 | utils.WriteUint32(&buf, v.Time, &offset) 19 | } 20 | return buf[:offset] 21 | } 22 | -------------------------------------------------------------------------------- /main_service/model/out/startgame.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func BuildStartRoom(id uint32) []byte { 9 | buf := make([]byte, 5) 10 | offset := 0 11 | utils.WriteUint8(&buf, constant.OUTStartRoom, &offset) 12 | utils.WriteUint32(&buf, id, &offset) 13 | return buf[:offset] 14 | } 15 | -------------------------------------------------------------------------------- /main_service/model/out/udp.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 6 | "github.com/KouKouChan/YuriCore/utils" 7 | ) 8 | 9 | func BuildUDPHolepunch(index uint16) []byte { 10 | buf := make([]byte, 3) 11 | offset := 0 12 | utils.WriteUint8(&buf, constant.UdpPacketSignature, &offset) 13 | utils.WriteUint16(&buf, index, &offset) 14 | return buf[:offset] 15 | } 16 | 17 | func UDPBuild(seq uint8, isHost uint8, userid uint32, ip uint32, port uint16) []byte { 18 | rst := packet.BuildHeader(seq, constant.PacketTypeUdp) 19 | buf := make([]byte, 12) 20 | offset := 0 21 | utils.WriteUint8(&buf, 1, &offset) 22 | utils.WriteUint8(&buf, isHost, &offset) 23 | utils.WriteUint32(&buf, userid, &offset) 24 | utils.WriteUint32BE(&buf, ip, &offset) 25 | utils.WriteUint16(&buf, port, &offset) 26 | rst = utils.BytesCombine(rst, buf) 27 | return rst 28 | } 29 | -------------------------------------------------------------------------------- /main_service/model/out/userroomstatus.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import "github.com/KouKouChan/YuriCore/utils" 4 | 5 | func BuildUserReadyStatus(id uint32, status uint8) []byte { 6 | buf := make([]byte, 8) 7 | offset := 0 8 | utils.WriteUint8(&buf, 3, &offset) 9 | utils.WriteUint32(&buf, id, &offset) 10 | utils.WriteUint8(&buf, status, &offset) 11 | return buf[:offset] 12 | } 13 | -------------------------------------------------------------------------------- /main_service/model/out/userstart.go: -------------------------------------------------------------------------------- 1 | package out 2 | 3 | import "github.com/KouKouChan/YuriCore/utils" 4 | 5 | func BuildUserStart(id uint32, username, nickname []byte) []byte { 6 | userbuf := make([]byte, 128) 7 | offset := 0 8 | utils.WriteUint32(&userbuf, id, &offset) 9 | utils.WriteStringWithNull(&userbuf, username, &offset) 10 | utils.WriteStringWithNull(&userbuf, nickname, &offset) 11 | utils.WriteUint8(&userbuf, 0, &offset) 12 | utils.WriteUint8(&userbuf, 0, &offset) 13 | utils.WriteUint8(&userbuf, 0, &offset) 14 | 15 | return userbuf[:offset] 16 | } 17 | -------------------------------------------------------------------------------- /main_service/model/packet/common.go: -------------------------------------------------------------------------------- 1 | package packet 2 | 3 | type ( 4 | //PacketHeader ,header of packet , 4 bytes len 5 | PacketHeader struct { 6 | Data []byte 7 | Sequence uint8 8 | Length uint16 9 | } 10 | //PacketData ,data part of packet 11 | PacketData struct { 12 | Data []byte 13 | Sequence uint8 14 | Length uint16 15 | Id uint8 16 | CurOffset int 17 | } 18 | ) 19 | 20 | -------------------------------------------------------------------------------- /main_service/model/packet/tools.go: -------------------------------------------------------------------------------- 1 | package packet 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/constant" 7 | ) 8 | 9 | //BuildHeader 建立数据包通用头部 10 | func BuildHeader(seq uint8, id uint8) []byte { 11 | header := make([]byte, 5) 12 | header[0] = constant.PacketTypeSignature 13 | header[1] = seq 14 | header[2] = 0 15 | header[3] = 0 16 | header[4] = id 17 | return header 18 | } 19 | 20 | //GetNextSeq 获取下一次的seq数据包序号 21 | func GetNextSeq(seq *uint8) uint8 { 22 | if *seq >= constant.MAXSEQUENCE { 23 | *seq = 0 24 | return 0 25 | } 26 | (*seq)++ 27 | return *seq 28 | } 29 | 30 | //SendPacket 发送数据包 31 | func SendPacket(data []byte, client net.Conn) { 32 | writeLen(&data) 33 | client.Write(data) 34 | } 35 | 36 | //WriteLen 写入数据长度到数据包通用头部 37 | func writeLen(data *[]byte) { 38 | headerL := uint16(len(*data)) - constant.HeaderLen 39 | (*data)[2] = uint8(headerL) 40 | (*data)[3] = uint8(headerL >> 8) 41 | } 42 | -------------------------------------------------------------------------------- /main_service/model/packet/udp.go: -------------------------------------------------------------------------------- 1 | package packet 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/constant" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | const () 9 | 10 | type InUDPmsg struct { 11 | Signature uint8 12 | UserId uint32 13 | PortId uint16 14 | IpAddress uint32 15 | Port uint16 16 | Seq uint8 17 | 18 | PacketData []byte 19 | Datalen int 20 | CurOffset int //可能32位 21 | ParsedSuccessfully bool 22 | } 23 | 24 | func (p InUDPmsg) IsHeartbeat() bool { 25 | return p.Datalen == 6 26 | } 27 | 28 | func (dest *InUDPmsg) PraseUDPpacket(data []byte, len int) bool { 29 | dest.CurOffset = 0 30 | dest.Signature = utils.ReadUint8(data, &dest.CurOffset) 31 | if dest.Signature != constant.UdpPacketSignature { 32 | dest.ParsedSuccessfully = false 33 | return false 34 | } 35 | dest.Datalen = len 36 | dest.PacketData = data 37 | if dest.IsHeartbeat() { 38 | } else { 39 | dest.UserId = utils.ReadUint32(data, &dest.CurOffset) 40 | dest.PortId = utils.ReadUint16(data, &dest.CurOffset) 41 | dest.IpAddress = utils.ReadUint32BE(data, &dest.CurOffset) 42 | dest.Port = utils.ReadUint16(data, &dest.CurOffset) 43 | dest.Seq = utils.ReadUint8(data, &dest.CurOffset) 44 | } 45 | dest.ParsedSuccessfully = true 46 | return true 47 | } 48 | -------------------------------------------------------------------------------- /main_service/model/server/channel.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | type Channel struct { 4 | ChannelIndex uint8 5 | ChannelName string 6 | ChannelStatus uint8 7 | ChannelType uint8 8 | 9 | Rooms []Room 10 | } 11 | 12 | const ( 13 | MAXCHANNELROOM = 0xFF 14 | ) 15 | -------------------------------------------------------------------------------- /main_service/model/server/room.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | type ( 4 | Unk40Struct struct { 5 | Unk40_unk00 uint8 6 | Unk40_unk01 uint8 7 | } 8 | Unk23Struct struct { 9 | Unk23_unk00 uint32 10 | Unk23_unk01 uint32 11 | Unk23_unk02 uint8 12 | Unk23_unk03 uint8 13 | Unk23_unk04 uint8 14 | Unk23_unk05 uint8 15 | Unk23_unk06 uint16 16 | Unk23_unk07 uint8 17 | Unk23_unk08 uint8 18 | } 19 | RoomSettingUnk struct { 20 | Unk00 uint8 21 | Unk01 uint8 22 | Unk02 uint8 23 | Unk03 uint8 24 | Unk04 uint32 25 | Unk14 uint8 26 | Unk15 uint8 27 | Unk16 uint8 28 | Unk17 uint8 29 | Unk18 uint8 30 | Unk19 uint8 31 | Unk23 []Unk23Struct 32 | Unk24 uint32 33 | Unk25 string 34 | Unk26 uint8 35 | Unk27 uint8 36 | Unk28 uint8 37 | Unk29 uint8 38 | Unk36 uint8 39 | Unk37 uint8 40 | Unk38 uint8 41 | Unk39 uint8 42 | Unk40 []Unk40Struct 43 | Unk41 uint8 44 | Unk42 uint8 45 | } 46 | Room struct { 47 | RoomId uint16 48 | RoomNumber uint8 49 | HostUserID uint32 50 | HostUserName string 51 | CanSpec uint8 52 | IsVipRoom uint8 53 | VipRoomLevel uint8 54 | 55 | //设置 56 | RoomName string 57 | PassWd string 58 | GameModeID uint8 59 | MapID uint8 60 | MaxPlayers uint8 61 | WinLimit uint8 62 | KillLimit uint16 63 | LevelLimit uint8 64 | GameTime uint8 65 | GameTimePerRound uint8 66 | WeaponRestrictions uint8 67 | Status uint8 68 | HostagePunish uint8 69 | StopTime uint8 70 | BuyLimitTime uint8 71 | ShowName uint8 72 | ShowFlash uint8 73 | ViewAngle uint8 74 | EnableVoice uint8 75 | LimitDeaths uint8 76 | TeamBalanceType uint8 77 | AreBotsEnabled uint8 78 | BotDifficulty uint8 79 | NumCtBots uint8 80 | NumTrBots uint8 81 | BotBalance uint8 82 | StartMoney uint16 83 | ChangeTeams uint8 84 | RespawnTime uint8 85 | NextMapEnabled uint8 86 | Difficulty uint8 87 | IsIngame uint8 88 | ForceCamera uint8 89 | DisableEnhancement uint8 90 | BombCountdown uint8 91 | FriendHurt uint8 92 | 93 | CountingDown bool 94 | Countdown uint8 95 | Users []uint32 96 | ParentChannelServer uint8 97 | ParentChannel uint8 98 | CtScore uint8 99 | TrScore uint8 100 | CtKillNum uint32 101 | TrKillNum uint32 102 | WinnerTeam uint8 103 | Cache []byte 104 | PageNum uint8 105 | 106 | Unk RoomSettingUnk 107 | } 108 | ) 109 | -------------------------------------------------------------------------------- /main_service/model/server/server.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | type Server struct { 4 | ServerIndex uint8 5 | ServerName string 6 | ServerStatus uint8 7 | ServerType uint8 8 | Channels []Channel 9 | } 10 | 11 | const ( 12 | MAXSERVERROOM = 0xFFFF 13 | ) 14 | -------------------------------------------------------------------------------- /main_service/model/user/cache.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "net" 5 | "sync" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/constant" 8 | ) 9 | 10 | type UserCache struct { 11 | UserID uint32 12 | UserName string 13 | NickName string 14 | 15 | UserInventory Inventory 16 | NetInfo UserNetInfo 17 | //连接 18 | CurrentConnection net.Conn 19 | CurrentSequence *uint8 20 | //频道房间信息 21 | CurrentServerIndex uint8 22 | CurrentChannelIndex uint8 23 | CurrentRoomId uint16 24 | CurrentTeam uint8 25 | Currentstatus uint8 26 | CurrentIsIngame bool 27 | CurrentKillNum uint16 28 | CurrentDeathNum uint16 29 | CurrentAssistNum uint16 30 | CurrentRoomData []byte 31 | 32 | SequenceLocker sync.Mutex 33 | } 34 | 35 | func (u *UserCache) IsUserReady() bool { 36 | return u.Currentstatus != constant.UserNotReady 37 | } 38 | 39 | func (u *UserCache) GetNextSeq() uint8 { 40 | u.SequenceLocker.Lock() 41 | defer u.SequenceLocker.Unlock() 42 | 43 | if *u.CurrentSequence >= constant.MAXSEQUENCE { 44 | *u.CurrentSequence = 0 45 | return 0 46 | } 47 | (*u.CurrentSequence)++ 48 | return *u.CurrentSequence 49 | } 50 | -------------------------------------------------------------------------------- /main_service/model/user/inventory.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | type ( 4 | UserLoadout struct { 5 | MainWeapon uint16 `json:"mainweapon" bson:"mainweapon"` 6 | SecondWeapon uint16 `json:"secondweapon" bson:"secondweapon"` 7 | Knife uint16 `json:"knife" bson:"knife"` 8 | Grenade uint16 `json:"grenade" bson:"grenade"` 9 | } 10 | 11 | UserBuyMenu struct { 12 | PistolsTR [9]uint16 `json:"pistolstr" bson:"pistolstr"` // 0 13 | PistolsCT [9]uint16 `json:"pistolsct" bson:"pistolsct"` // 7 14 | ShotgunsTR [9]uint16 `json:"shotgunstr" bson:"shotgunstr"` // 1 15 | ShotgunsCT [9]uint16 `json:"shotgunsct" bson:"shotgunsct"` // 8 16 | SmgsTR [9]uint16 `json:"smgstr" bson:"smgstr"` // 2 17 | SmgsCT [9]uint16 `json:"smgsct" bson:"smgsct"` // 9 18 | RiflesTR [9]uint16 `json:"riflestr" bson:"riflestr"` // 3 19 | RiflesCT [9]uint16 `json:"riflesct" bson:"riflesct"` // 10 20 | MachinegunsTR [9]uint16 `json:"machinegunstr" bson:"machinegunstr"` // 4 21 | MachinegunsCT [9]uint16 `json:"machinegunsct" bson:"machinegunsct"` // 11 22 | MeleesTR [9]uint16 `json:"meleestr" bson:"meleestr"` // 14 23 | MeleesCT [9]uint16 `json:"meleesct" bson:"meleesct"` // 15 24 | EquipmentTR [9]uint16 `json:"equipmenttr" bson:"equipmenttr"` // 5 25 | EquipmentCT [9]uint16 `json:"equipmentct" bson:"equipmentct"` // 12 26 | ClassesTR [9]uint16 `json:"classestr" bson:"classestr"` // 6 27 | ClassesCT [9]uint16 `json:"classesct" bson:"classesct"` // 13 28 | } 29 | 30 | UserInventoryItem struct { 31 | Id uint16 `json:"id" bson:"id"` //物品id 32 | Count uint16 `json:"count" bson:"count"` //数量 33 | Existed uint8 `json:"existed" bson:"existed"` 34 | Type uint8 `json:"type" bson:"type"` 35 | Time uint32 `json:"time" bson:"time"` 36 | } 37 | 38 | UserCosmetics struct { 39 | CosmeticsName string `json:"cosmeticsname" bson:"cosmeticsname"` 40 | MainWeapon uint16 `json:"mainweapon" bson:"mainweapon"` 41 | MainBullet uint16 `json:"mainbullet" bson:"mainbullet"` 42 | SecondWeapon uint16 `json:"secondweapon" bson:"secondweapon"` 43 | SecondBullet uint16 `json:"secondBullet" bson:"secondBullet"` 44 | FlashbangNum uint16 `json:"flashbangnum" bson:"flashbangnum"` 45 | GrenadeID uint16 `json:"grenadeid" bson:"grenadeid"` 46 | SmokeNum uint16 `json:"smokenum" bson:"smokenum"` 47 | DefuserNum uint16 `json:"defusernum" bson:"defusernum"` 48 | TelescopeNum uint16 `json:"telescopenum" bson:"telescopenum"` 49 | BulletproofNum uint16 `json:"Bulletproofnum" bson:"Bulletproofnum"` 50 | KnifeID uint16 `json:"knifeid" bson:"knifeid"` 51 | } 52 | 53 | Inventory struct { 54 | Items []UserInventoryItem `json:"items" bson:"items"` //物品 55 | BuyMenu UserBuyMenu `json:"buymenu" bson:"buymenu"` //购买菜单 56 | Cosmetics [5]UserCosmetics `json:"cosmetics" bson:"cosmetics"` 57 | Loadouts [3]UserLoadout `json:"loadouts" bson:"loadouts"` 58 | } 59 | ) 60 | -------------------------------------------------------------------------------- /main_service/model/user/user.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | type ( 4 | UserNetInfo struct { 5 | ExternalIpAddress uint32 6 | ExternalClientPort uint16 7 | ExternalServerPort uint16 8 | 9 | LocalIpAddress uint32 10 | LocalClientPort uint16 11 | LocalServerPort uint16 12 | } 13 | 14 | UserInfo struct { 15 | UserID uint32 `json:"userid" bson:"-"` 16 | UserName string `json:"username" bson:"username"` 17 | NickName string `json:"nickname" bson:"nickname"` 18 | Password string `json:"password" bson:"password"` 19 | Level uint8 `json:"level" bson:"level"` 20 | CurExp uint64 `json:"curexp" bson:"curexp"` 21 | MaxExp uint64 `json:"maxexp" bson:"maxexp"` 22 | Points uint64 `json:"points" bson:"points"` 23 | PlayedMatches uint32 `json:"playedmatches" bson:"playedmatches"` 24 | Wins uint32 `json:"wins" bson:"wins"` 25 | Kills uint32 `json:"kills" bson:"kills"` 26 | Deaths uint32 `json:"deaths" bson:"deaths"` 27 | Campaign uint8 `json:"campaign" bson:"campaign"` 28 | Rank uint32 `json:"rank" bson:"rank"` 29 | ChatTimes uint8 `json:"chatimes" bson:"chatimes"` 30 | Options []byte `json:"options" bson:"options"` 31 | 32 | UserInventory Inventory `json:"inventory" bson:"inventory"` 33 | NetInfo UserNetInfo `json:"netinfo" bson:"-"` 34 | Friends []string `json:"friends" bson:"friends"` 35 | } 36 | ) 37 | -------------------------------------------------------------------------------- /main_service/service/character/new.go: -------------------------------------------------------------------------------- 1 | package character 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type NewService interface { 16 | Handle(ctx context.Context) error 17 | } 18 | 19 | type newServiceImpl struct { 20 | nickname string 21 | client net.Conn 22 | } 23 | 24 | func GetNewServiceImpl(nickname string, client net.Conn) NewService { 25 | return &newServiceImpl{ 26 | nickname: nickname, 27 | client: client, 28 | } 29 | } 30 | 31 | func (n *newServiceImpl) Handle(ctx context.Context) error { 32 | u := client.GetUserCacheClient().GetUserByConnection(ctx, n.client) 33 | if u == nil { 34 | return errors.New("can't find user") 35 | } 36 | 37 | if u.NickName != "" { 38 | out.OnSendMessage(u.GetNextSeq(), u.CurrentConnection, constant.MessageDialogBox, constant.CSO_NewCharacter_Failed) 39 | return errors.New("user already has nickname") 40 | } 41 | 42 | userinfo, err := client.GetUserClient().UpdateNickname(ctx, u.UserID, n.nickname) 43 | if err != nil { 44 | out.OnSendMessage(u.GetNextSeq(), u.CurrentConnection, constant.MessageDialogBox, constant.CSO_NewCharacter_Failed) 45 | return errors.New("change nickname failed!") 46 | } 47 | 48 | // UserReply部分 49 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeReply), out.BuildNicknameReply()) 50 | packet.SendPacket(rst, u.CurrentConnection) 51 | 52 | // UserStart部分 53 | rst = utils.BytesCombine(packet.BuildHeader( 54 | u.GetNextSeq(), constant.PacketTypeUserStart), 55 | out.BuildUserStart(userinfo.UserID, []byte(userinfo.UserName), []byte(userinfo.NickName))) 56 | packet.SendPacket(rst, u.CurrentConnection) 57 | 58 | // UserInfo部分 59 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeUserInfo), out.BuildUserInfo(out.NewUserInfo(userinfo), true, 0xFFFFFFFF)) 60 | packet.SendPacket(rst, u.CurrentConnection) 61 | 62 | // ServerList部分 63 | servers, err := client.GetRoomClient().GetServiceList(ctx) 64 | if err != nil { 65 | return err 66 | } 67 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeServerList), out.BuildServerList(servers)) 68 | packet.SendPacket(rst, u.CurrentConnection) 69 | 70 | // Inventory部分 71 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeInventory_Create), out.BuildUserInventory(&userinfo.UserInventory)) 72 | packet.SendPacket(rst, u.CurrentConnection) 73 | 74 | // buymenu 75 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeFavorite), out.BuildUserBuymenu(&userinfo.UserInventory.BuyMenu)) 76 | packet.SendPacket(rst, u.CurrentConnection) 77 | 78 | // bag 79 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeFavorite), out.BuildUserBag(userinfo.UserInventory.Loadouts)) 80 | packet.SendPacket(rst, u.CurrentConnection) 81 | 82 | // cosmetics 83 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeFavorite), out.BuildUserCosmetics(userinfo.UserInventory.Cosmetics)) 84 | packet.SendPacket(rst, u.CurrentConnection) 85 | 86 | // option 87 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeOption), out.BuildUserOptions(userinfo)) 88 | packet.SendPacket(rst, u.CurrentConnection) 89 | 90 | return client.GetUserCacheClient().SetNickname(ctx, u.UserID, userinfo.NickName) 91 | } 92 | -------------------------------------------------------------------------------- /main_service/service/chat/chat.go: -------------------------------------------------------------------------------- 1 | package chat 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | "strconv" 8 | "strings" 9 | 10 | "github.com/KouKouChan/YuriCore/main_service/client" 11 | "github.com/KouKouChan/YuriCore/main_service/constant" 12 | "github.com/KouKouChan/YuriCore/main_service/model/out" 13 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 14 | "github.com/KouKouChan/YuriCore/utils" 15 | . "github.com/KouKouChan/YuriCore/verbose" 16 | ) 17 | 18 | type ChatInfra interface { 19 | ChannelHandler(ctx context.Context) error 20 | RoomHandler(ctx context.Context) error 21 | } 22 | 23 | type chatInfraImpl struct { 24 | message string 25 | client net.Conn 26 | } 27 | 28 | func GetChatInfra(data string, client net.Conn) ChatInfra { 29 | return &chatInfraImpl{ 30 | message: data, 31 | client: client, 32 | } 33 | } 34 | 35 | func (c *chatInfraImpl) ChannelHandler(ctx context.Context) error { 36 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 37 | if u == nil { 38 | return errors.New("can't find user") 39 | } 40 | 41 | // 找到所有用户 42 | msg := out.BuildChannelMessage(u.NickName, c.message) 43 | users := client.GetUserCacheClient().GetChannelNoRoomUsers(ctx, u.CurrentServerIndex, u.CurrentChannelIndex) 44 | for i := range users { 45 | if users[i] == u.UserID { 46 | continue 47 | } 48 | player := client.GetUserCacheClient().GetUserByID(ctx, users[i]) 49 | if player == nil { 50 | continue 51 | } 52 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeChat), msg) 53 | packet.SendPacket(rst, player.CurrentConnection) 54 | } 55 | 56 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeChat), msg) 57 | packet.SendPacket(rst, u.CurrentConnection) 58 | 59 | DebugPrintf(2, "User %+v said channel message %+v", u.UserName, c.message) 60 | return nil 61 | } 62 | 63 | func (c *chatInfraImpl) RoomHandler(ctx context.Context) error { 64 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 65 | if u == nil { 66 | return errors.New("can't find user") 67 | } 68 | 69 | if u.CurrentRoomId == 0 { 70 | return errors.New("user try to speak but not in room") 71 | } 72 | 73 | room, err := client.GetRoomClient().GetRoomInfo(ctx, u.CurrentRoomId) 74 | if err != nil { 75 | return err 76 | } 77 | 78 | strs := strings.Fields(c.message) 79 | if len(strs) >= 2 { 80 | switch strs[0] { 81 | case "/bot": 82 | if room.HostUserID != u.UserID || len(strs) != 3 { 83 | goto nocmd 84 | } 85 | 86 | CTBot, err := strconv.Atoi(strs[1]) 87 | if err != nil { 88 | msg := out.BuildRoomMessage("YuriCore", "wrong ct bot number!") 89 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeChat), msg) 90 | packet.SendPacket(rst, u.CurrentConnection) 91 | return err 92 | } 93 | strs[2] = strings.Replace(strs[2], "\x00", "", -1) 94 | TRBot, err := strconv.Atoi(strs[2]) 95 | if err != nil { 96 | msg := out.BuildRoomMessage("YuriCore", "wrong tr bot number!") 97 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeChat), msg) 98 | packet.SendPacket(rst, u.CurrentConnection) 99 | return err 100 | } 101 | room.NumCtBots = uint8(CTBot) 102 | room.NumTrBots = uint8(TRBot) 103 | case "/money": 104 | if room.HostUserID != u.UserID || len(strs) != 2 { 105 | goto nocmd 106 | } 107 | 108 | strs[1] = strings.Replace(strs[1], "\x00", "", -1) 109 | Money, err := strconv.Atoi(strs[1]) 110 | if err != nil { 111 | msg := out.BuildRoomMessage("YuriCore", "wrong money number!") 112 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeChat), msg) 113 | packet.SendPacket(rst, u.CurrentConnection) 114 | return err 115 | } 116 | room.StartMoney = uint16(Money) 117 | default: 118 | goto nocmd 119 | } 120 | 121 | room, err = client.GetRoomClient().UpdateRoomSafe(ctx, room) 122 | if err != nil { 123 | return err 124 | } 125 | if room == nil || room.RoomId == 0 || room.HostUserID != u.UserID { 126 | return errors.New("got null resp or user is not host") 127 | } 128 | 129 | // 给所有玩家发送 130 | setting := utils.BytesCombine([]byte{constant.OUTUpdateSettings}, out.BuildRoomSetting(room, 0xFFFFFFFF7FFFFFFF)) 131 | 132 | for i := range room.Users { 133 | dest_player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 134 | if dest_player == nil { 135 | continue 136 | } 137 | rst := utils.BytesCombine(packet.BuildHeader(dest_player.GetNextSeq(), constant.PacketTypeRoom), setting) 138 | packet.SendPacket(rst, dest_player.CurrentConnection) 139 | } 140 | 141 | msg := out.BuildRoomMessage("YuriCore", "done!") 142 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeChat), msg) 143 | packet.SendPacket(rst, u.CurrentConnection) 144 | return nil 145 | } 146 | 147 | nocmd: 148 | msg := out.BuildRoomMessage(u.NickName, c.message) 149 | for i := range room.Users { 150 | player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 151 | if player == nil { 152 | continue 153 | } 154 | // TODO 游戏内是否听到 155 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeChat), msg) 156 | packet.SendPacket(rst, player.CurrentConnection) 157 | } 158 | 159 | DebugPrintf(2, "User %+v said room message %+v", u.UserName, c.message) 160 | return nil 161 | } 162 | -------------------------------------------------------------------------------- /main_service/service/disconnect/disconnect.go: -------------------------------------------------------------------------------- 1 | package disconnect 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | "time" 8 | 9 | "github.com/KouKouChan/YuriCore/main_service/client" 10 | "github.com/KouKouChan/YuriCore/main_service/constant" 11 | "github.com/KouKouChan/YuriCore/main_service/model/out" 12 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 13 | "github.com/KouKouChan/YuriCore/main_service/service/room" 14 | "github.com/KouKouChan/YuriCore/utils" 15 | ) 16 | 17 | type DisconnectService interface { 18 | Handle(ctx context.Context) error 19 | } 20 | 21 | type disconnectServiceImpl struct { 22 | client net.Conn 23 | } 24 | 25 | func NewDisconnectService(client net.Conn) DisconnectService { 26 | return &disconnectServiceImpl{ 27 | client: client, 28 | } 29 | } 30 | 31 | func (d *disconnectServiceImpl) Handle(ctx context.Context) error { 32 | u := client.GetUserCacheClient().GetUserByConnection(ctx, d.client) 33 | if u == nil { 34 | return errors.New("can't find user") 35 | } 36 | // 是否在频道内 37 | if u.CurrentServerIndex != 0 && u.CurrentChannelIndex != 0 { 38 | // 找到所有用户 39 | userIDs := client.GetUserCacheClient().GetChannelUsers(ctx, u.CurrentServerIndex, u.CurrentChannelIndex) 40 | 41 | // lobby 42 | lobbyleave := out.BuildLobbyLeave(u.UserID) 43 | for i := range userIDs { 44 | player := client.GetUserCacheClient().GetUserByID(ctx, userIDs[i]) 45 | if player == nil { 46 | continue 47 | } 48 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeLobby), lobbyleave) 49 | packet.SendPacket(rst, player.CurrentConnection) 50 | } 51 | } 52 | 53 | // 是否在房间内 54 | if u.CurrentRoomId != 0 { 55 | room.NewLeaveRoomService(d.client).UserRoomEnd(ctx, u) 56 | } 57 | 58 | // 删除用户 59 | uid := u.UserID 60 | client.GetUserCacheClient().DeleteUserByID(ctx, uid) 61 | 62 | // 等待用户数据刷新 63 | time.Sleep(time.Second / 4) 64 | _, err := client.GetUserClient().UserDown(ctx, uid) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | return nil 70 | } 71 | -------------------------------------------------------------------------------- /main_service/service/favorate/setbag.go: -------------------------------------------------------------------------------- 1 | package favorate 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type SetBagService interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type setBagServiceImpl struct { 18 | p *packet.PacketData 19 | client net.Conn 20 | } 21 | 22 | func NewSetBagService(p *packet.PacketData, client net.Conn) SetBagService { 23 | return &setBagServiceImpl{ 24 | p: p, 25 | client: client, 26 | } 27 | } 28 | 29 | func (s *setBagServiceImpl) Handle(ctx context.Context) error { 30 | u := client.GetUserCacheClient().GetUserByConnection(ctx, s.client) 31 | if u == nil { 32 | return errors.New("can't find user") 33 | } 34 | 35 | subtype := utils.ReadUint8(s.p.Data, &s.p.CurOffset) 36 | 37 | switch subtype { 38 | case 0: 39 | 40 | case 1: 41 | 42 | case 2: 43 | 44 | default: 45 | if subtype < 10 || subtype >= 40 { 46 | return errors.New("wrong set bag type") 47 | } 48 | 49 | bag := subtype/10 - 1 50 | slot := subtype % 10 51 | 52 | if slot > 3 { 53 | return errors.New("wrong set bag slot") 54 | } 55 | 56 | item := utils.ReadUint16(s.p.Data, &s.p.CurOffset) 57 | 58 | info, err := client.GetUserClient().UpdateBag(ctx, u.UserID, uint16(bag), slot, item) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | if info == nil || info.UserID == 0 { 64 | return errors.New("get null user for update bag") 65 | } 66 | 67 | err = client.GetUserCacheClient().FlushUserInventory(ctx, info.UserID, &info.UserInventory) 68 | if err != nil { 69 | return err 70 | } 71 | 72 | } 73 | 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /main_service/service/favorate/setbuymenu.go: -------------------------------------------------------------------------------- 1 | package favorate 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type SetBuymenuService interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type setBuymenuService struct { 18 | buymenuID uint8 19 | sloutID uint8 20 | ItemID uint16 21 | client net.Conn 22 | } 23 | 24 | func NewSetBuymenuService(p *packet.PacketData, client net.Conn) SetBuymenuService { 25 | return &setBuymenuService{ 26 | buymenuID: utils.ReadUint8(p.Data, &p.CurOffset), 27 | sloutID: utils.ReadUint8(p.Data, &p.CurOffset), 28 | ItemID: utils.ReadUint16(p.Data, &p.CurOffset), 29 | client: client, 30 | } 31 | } 32 | 33 | func (s *setBuymenuService) Handle(ctx context.Context) error { 34 | u := client.GetUserCacheClient().GetUserByConnection(ctx, s.client) 35 | if u == nil { 36 | return errors.New("can't find user") 37 | } 38 | 39 | _, err := client.GetUserClient().UpdateBuymenu(ctx, u.UserID, uint16(s.buymenuID), s.sloutID, s.ItemID) 40 | return err 41 | } 42 | -------------------------------------------------------------------------------- /main_service/service/favorate/setcosmetics.go: -------------------------------------------------------------------------------- 1 | package favorate 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 10 | "github.com/KouKouChan/YuriCore/main_service/model/user" 11 | "github.com/KouKouChan/YuriCore/utils" 12 | ) 13 | 14 | type SetCosmeticsService interface { 15 | Handle(ctx context.Context) error 16 | } 17 | 18 | type setCosmeticsService struct { 19 | CosmeticsID uint8 20 | cosmetics *user.UserCosmetics 21 | client net.Conn 22 | } 23 | 24 | func NewSetCosmeticsService(p *packet.PacketData, client net.Conn) SetCosmeticsService { 25 | return &setCosmeticsService{ 26 | CosmeticsID: utils.ReadUint8(p.Data, &p.CurOffset), 27 | cosmetics: &user.UserCosmetics{ 28 | CosmeticsName: utils.ReadStringToNULL(p.Data, &p.CurOffset), 29 | MainWeapon: utils.ReadUint16(p.Data, &p.CurOffset), 30 | MainBullet: utils.ReadUint16(p.Data, &p.CurOffset), 31 | SecondWeapon: utils.ReadUint16(p.Data, &p.CurOffset), 32 | SecondBullet: utils.ReadUint16(p.Data, &p.CurOffset), 33 | FlashbangNum: utils.ReadUint16(p.Data, &p.CurOffset), 34 | GrenadeID: utils.ReadUint16(p.Data, &p.CurOffset), 35 | SmokeNum: utils.ReadUint16(p.Data, &p.CurOffset), 36 | DefuserNum: utils.ReadUint16(p.Data, &p.CurOffset), 37 | TelescopeNum: utils.ReadUint16(p.Data, &p.CurOffset), 38 | BulletproofNum: utils.ReadUint16(p.Data, &p.CurOffset), 39 | KnifeID: utils.ReadUint16(p.Data, &p.CurOffset), 40 | }, 41 | client: client, 42 | } 43 | } 44 | 45 | func (s *setCosmeticsService) Handle(ctx context.Context) error { 46 | u := client.GetUserCacheClient().GetUserByConnection(ctx, s.client) 47 | if u == nil { 48 | return errors.New("can't find user") 49 | } 50 | 51 | _, err := client.GetUserClient().UpdateCosmetics(ctx, u.UserID, s.CosmeticsID, s.cosmetics) 52 | return err 53 | } 54 | -------------------------------------------------------------------------------- /main_service/service/host/data.go: -------------------------------------------------------------------------------- 1 | package host 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type GameDataService interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type gameDataServiceImpl struct { 18 | data []byte 19 | client net.Conn 20 | } 21 | 22 | func NewGameDataService(p *packet.PacketData, client net.Conn) GameDataService { 23 | len := utils.ReadUint16(p.Data, &p.CurOffset) 24 | return &gameDataServiceImpl{ 25 | data: utils.ReadString(p.Data, &p.CurOffset, int(len)), 26 | client: client, 27 | } 28 | } 29 | 30 | func (g *gameDataServiceImpl) Handle(ctx context.Context) error { 31 | u := client.GetUserCacheClient().GetUserByConnection(ctx, g.client) 32 | if u == nil || u.CurrentRoomId == 0 { 33 | return errors.New("can't find user or user not in room") 34 | } 35 | 36 | if u.CurrentRoomId == 0 { 37 | return errors.New("user send game data but is not host") 38 | } 39 | 40 | return client.GetUserCacheClient().FlushUserRoomData(ctx, u.UserID, g.data) 41 | } 42 | -------------------------------------------------------------------------------- /main_service/service/host/gameend.go: -------------------------------------------------------------------------------- 1 | package host 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type GameEndService interface { 16 | Handle(ctx context.Context) error 17 | } 18 | 19 | type gameEndServiceImpl struct { 20 | client net.Conn 21 | } 22 | 23 | func NewGameEndService(client net.Conn) GameEndService { 24 | return &gameEndServiceImpl{ 25 | client: client, 26 | } 27 | } 28 | 29 | func (g *gameEndServiceImpl) Handle(ctx context.Context) error { 30 | u := client.GetUserCacheClient().GetUserByConnection(ctx, g.client) 31 | if u == nil || u.CurrentRoomId == 0 { 32 | return errors.New("can't find user or user not in room") 33 | } 34 | 35 | // TODO 修改房间状态 36 | room, err := client.GetRoomClient().EndGame(ctx, u.UserID, u.CurrentRoomId) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | // 发送结果 42 | setting := utils.BytesCombine([]byte{constant.OUTUpdateSettings}, out.BuildRoomSetting(room, 0xFFFFFFFF7FFFFFFF)) 43 | hoststop := out.BuildHostStop() 44 | result := out.BuildRoomResult(room) 45 | for i := range room.Users { 46 | player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 47 | if player == nil { 48 | continue 49 | } 50 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoom), setting) 51 | packet.SendPacket(rst, player.CurrentConnection) 52 | 53 | if player.CurrentIsIngame { 54 | // 发送hoststop 55 | rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeHost), hoststop) 56 | packet.SendPacket(rst, player.CurrentConnection) 57 | 58 | // 发送结果 59 | rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoom), result) 60 | packet.SendPacket(rst, player.CurrentConnection) 61 | 62 | client.GetUserCacheClient().SetUserIngame(ctx, player.UserID, false) 63 | } 64 | client.GetUserCacheClient().SetUserStatus(ctx, player.UserID, constant.UserNotReady) 65 | 66 | temp := out.BuildUserReadyStatus(player.UserID, player.Currentstatus) 67 | for j := range room.Users { 68 | dest_player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[j]) 69 | if dest_player == nil { 70 | continue 71 | } 72 | rst = utils.BytesCombine(packet.BuildHeader(dest_player.GetNextSeq(), constant.PacketTypeRoom), temp) 73 | packet.SendPacket(rst, dest_player.CurrentConnection) 74 | } 75 | } 76 | 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /main_service/service/host/inventory.go: -------------------------------------------------------------------------------- 1 | package host 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type GetInventoryService interface { 16 | Handle(ctx context.Context) error 17 | } 18 | 19 | type getInventoryServiceImpl struct { 20 | dest uint32 21 | client net.Conn 22 | } 23 | 24 | func NewGetInventoryService(p *packet.PacketData, client net.Conn) GetInventoryService { 25 | return &getInventoryServiceImpl{ 26 | dest: utils.ReadUint32(p.Data, &p.CurOffset), 27 | client: client, 28 | } 29 | } 30 | 31 | func (g *getInventoryServiceImpl) Handle(ctx context.Context) error { 32 | u := client.GetUserCacheClient().GetUserByConnection(ctx, g.client) 33 | if u == nil || u.CurrentRoomId == 0 { 34 | return errors.New("can't find user or user not in room") 35 | } 36 | 37 | room, err := client.GetRoomClient().GetRoomInfo(ctx, u.CurrentRoomId) 38 | if err != nil { 39 | return err 40 | } 41 | if room.HostUserID != u.UserID { 42 | return errors.New("user try to get other player's inventory but is not host") 43 | } 44 | 45 | dest_player := client.GetUserCacheClient().GetUserByID(ctx, g.dest) 46 | if dest_player == nil || dest_player.CurrentRoomId != u.CurrentRoomId { 47 | return errors.New("can't find dest player or player not in room") 48 | } 49 | 50 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeHost), out.BuildSetUserInventory(dest_player)) 51 | packet.SendPacket(rst, u.CurrentConnection) 52 | 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /main_service/service/host/itemuse.go: -------------------------------------------------------------------------------- 1 | package host 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | . "github.com/KouKouChan/YuriCore/verbose" 14 | ) 15 | 16 | type ItemUsingService interface { 17 | Handle(ctx context.Context) error 18 | } 19 | 20 | type itemUsingServiceImpl struct { 21 | UserID uint32 22 | ItemID uint16 23 | Unk00 uint8 24 | Unk01 uint8 25 | client net.Conn 26 | } 27 | 28 | func NewItemUsingService(p *packet.PacketData, client net.Conn) ItemUsingService { 29 | return &itemUsingServiceImpl{ 30 | UserID: utils.ReadUint32(p.Data, &p.CurOffset), 31 | ItemID: utils.ReadUint16(p.Data, &p.CurOffset), 32 | Unk00: utils.ReadUint8(p.Data, &p.CurOffset), 33 | Unk01: utils.ReadUint8(p.Data, &p.CurOffset), 34 | client: client, 35 | } 36 | } 37 | 38 | func (i *itemUsingServiceImpl) Handle(ctx context.Context) error { 39 | host := client.GetUserCacheClient().GetUserByConnection(ctx, i.client) 40 | if host == nil || host.CurrentRoomId == 0 { 41 | return errors.New("can't find user or user not in room") 42 | } 43 | 44 | dest_u := client.GetUserCacheClient().GetUserByID(ctx, i.UserID) 45 | if dest_u == nil || dest_u.CurrentRoomId == 0 { 46 | return errors.New("can't find dest_user or dest_user not in room") 47 | } 48 | 49 | // 发送结果 50 | rst := utils.BytesCombine( 51 | packet.BuildHeader( 52 | host.GetNextSeq(), 53 | constant.PacketTypeHost, 54 | ), 55 | out.BuildHostItemUsing(dest_u.UserID, i.ItemID, 1), 56 | ) 57 | packet.SendPacket(rst, host.CurrentConnection) 58 | DebugPrintf(2, "User %+v used item=%+v in match", dest_u.UserName, i.ItemID) 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /main_service/service/host/start.go: -------------------------------------------------------------------------------- 1 | package host 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | . "github.com/KouKouChan/YuriCore/verbose" 14 | ) 15 | 16 | type StartService interface { 17 | Handle(ctx context.Context) error 18 | } 19 | 20 | type startServiceImpl struct { 21 | client net.Conn 22 | } 23 | 24 | func NewStartService(client net.Conn) StartService { 25 | return &startServiceImpl{ 26 | client: client, 27 | } 28 | } 29 | 30 | func (c *startServiceImpl) Handle(ctx context.Context) error { 31 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 32 | if u == nil || u.CurrentRoomId == 0 { 33 | return errors.New("can't find user or user not in room") 34 | } 35 | 36 | // 判断用户房间 37 | if u.CurrentRoomId == 0 { 38 | return errors.New("user started game server but not in room") 39 | } 40 | 41 | room, err := client.GetRoomClient().GetRoomInfo(ctx, u.CurrentRoomId) 42 | if err != nil { 43 | return err 44 | } 45 | if room.HostUserID != u.UserID { 46 | return errors.New("user started game server but is not host") 47 | } 48 | 49 | // 给所有玩家发送// 给所有玩家发送 50 | setting := utils.BytesCombine([]byte{constant.OUTUpdateSettings}, out.BuildRoomSetting(room, 0xFFFFFFFF7FFFFFFF)) 51 | for i := range room.Users { 52 | player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 53 | if player == nil { 54 | continue 55 | } 56 | 57 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoom), setting) 58 | packet.SendPacket(rst, player.CurrentConnection) 59 | 60 | if player.UserID != u.UserID { 61 | if player.IsUserReady() { 62 | client.GetUserCacheClient().ResetAssistNum(ctx, player.UserID) 63 | client.GetUserCacheClient().ResetDeadNum(ctx, player.UserID) 64 | client.GetUserCacheClient().ResetKillNum(ctx, player.UserID) 65 | client.GetUserCacheClient().SetUserIngame(ctx, player.UserID, true) 66 | // //给主机发送其他人的数据 67 | // rst := out.UDPBuild(u.GetNextSeq(), 0, player.UserID, player.NetInfo.ExternalIpAddress, 27005) 68 | // packet.SendPacket(rst, u.CurrentConnection) 69 | // //连接到主机 70 | // rst = out.UDPBuild(player.GetNextSeq(), 1, u.UserID, u.NetInfo.ExternalIpAddress, 27005) 71 | // packet.SendPacket(rst, player.CurrentConnection) 72 | // //加入主机 73 | // rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeHost), out.BuildJoinHost(u.UserID)) 74 | // packet.SendPacket(rst, player.CurrentConnection) 75 | rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeHost), out.BuildConnectHost(u.NetInfo.ExternalIpAddress, 27005)) 76 | packet.SendPacket(rst, player.CurrentConnection) 77 | } 78 | } 79 | 80 | temp := out.BuildUserReadyStatus(player.UserID, player.Currentstatus) 81 | for j := range room.Users { 82 | dest_player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[j]) 83 | if dest_player == nil { 84 | continue 85 | } 86 | rst = utils.BytesCombine(packet.BuildHeader(dest_player.GetNextSeq(), constant.PacketTypeRoom), temp) 87 | packet.SendPacket(rst, dest_player.CurrentConnection) 88 | } 89 | 90 | } 91 | 92 | DebugPrintf(2, "User %+v started game server", u.UserName) 93 | return nil 94 | } 95 | -------------------------------------------------------------------------------- /main_service/service/option/option.go: -------------------------------------------------------------------------------- 1 | package option 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 10 | "github.com/KouKouChan/YuriCore/utils" 11 | ) 12 | 13 | type OptionService interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type optionServiceImpl struct { 18 | data []byte 19 | client net.Conn 20 | } 21 | 22 | func NewOptionService(p *packet.PacketData, client net.Conn) OptionService { 23 | len := utils.ReadUint16(p.Data, &p.CurOffset) 24 | return &optionServiceImpl{ 25 | data: utils.ReadString(p.Data, &p.CurOffset, int(len)), 26 | client: client, 27 | } 28 | } 29 | 30 | func (s *optionServiceImpl) Handle(ctx context.Context) error { 31 | u := client.GetUserCacheClient().GetUserByConnection(ctx, s.client) 32 | if u == nil { 33 | return errors.New("can't find user") 34 | } 35 | 36 | _, err := client.GetUserClient().UpdateOptions(ctx, u.UserID, s.data) 37 | 38 | return err 39 | } 40 | -------------------------------------------------------------------------------- /main_service/service/playerinfo/playerinfo.go: -------------------------------------------------------------------------------- 1 | package playerinfo 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type UpdateCampaignService interface { 16 | Handle(ctx context.Context) error 17 | } 18 | 19 | type updateCampaignServiceImpl struct { 20 | client net.Conn 21 | subtype uint8 22 | campaignID uint8 23 | } 24 | 25 | func NewUpdateCampaignService(p *packet.PacketData, client net.Conn) UpdateCampaignService { 26 | return &updateCampaignServiceImpl{ 27 | client: client, 28 | subtype: utils.ReadUint8(p.Data, &p.CurOffset), 29 | campaignID: utils.ReadUint8(p.Data, &p.CurOffset), 30 | } 31 | } 32 | 33 | func (u *updateCampaignServiceImpl) Handle(ctx context.Context) error { 34 | user := client.GetUserCacheClient().GetUserByConnection(ctx, u.client) 35 | if user == nil || user.UserID == 0 { 36 | return errors.New("can't find user") 37 | } 38 | 39 | if u.subtype != 1 { 40 | return errors.New("not update campaign request") 41 | } 42 | 43 | switch u.campaignID { 44 | case 1, 2, 4, 8, 16, 32: 45 | info, err := client.GetUserClient().UpdateCampaign(ctx, user.UserID, u.campaignID) 46 | if err != nil { 47 | return err 48 | } 49 | 50 | // UserInfo部分 51 | rst := utils.BytesCombine(packet.BuildHeader(user.GetNextSeq(), constant.PacketTypeUserInfo), out.BuildUserInfo(out.NewUserInfo(info), true, 0xFFFFFFFF)) 52 | packet.SendPacket(rst, user.CurrentConnection) 53 | 54 | return nil 55 | default: 56 | return errors.New("Unknown canpaign id") 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /main_service/service/register/register.go: -------------------------------------------------------------------------------- 1 | package register 2 | 3 | import ( 4 | "context" 5 | "net" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/client" 8 | "github.com/KouKouChan/YuriCore/main_service/constant" 9 | "github.com/KouKouChan/YuriCore/main_service/model/out" 10 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 11 | ) 12 | 13 | type RegisterService interface { 14 | Handle(ctx context.Context) error 15 | } 16 | 17 | type registerServiceImpl struct { 18 | username string 19 | password string 20 | client net.Conn 21 | seq *uint8 22 | } 23 | 24 | func GetRegisterServiceImpl(username, password string, client net.Conn, seq *uint8) RegisterService { 25 | return ®isterServiceImpl{ 26 | username: username, 27 | password: password, 28 | client: client, 29 | seq: seq, 30 | } 31 | } 32 | 33 | func (r *registerServiceImpl) Handle(ctx context.Context) error { 34 | ok, err := client.GetUserClient().Register(ctx, r.username, r.password) 35 | if err != nil { 36 | out.OnSendMessage(packet.GetNextSeq(r.seq), r.client, constant.MessageDialogBox, constant.CSO_Register_ServerFailed) 37 | return err 38 | } 39 | if !ok { 40 | out.OnSendMessage(packet.GetNextSeq(r.seq), r.client, constant.MessageDialogBox, constant.CSO_Register_Failed) 41 | return err 42 | } 43 | 44 | out.OnSendMessage(packet.GetNextSeq(r.seq), r.client, constant.MessageDialogBox, constant.CSO_Register_Success) 45 | 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /main_service/service/room/changeteam.go: -------------------------------------------------------------------------------- 1 | package room 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type ChangeTeamService interface { 16 | Handle(ctx context.Context) error 17 | } 18 | 19 | type changeTeamServiceImpl struct { 20 | team uint8 21 | client net.Conn 22 | } 23 | 24 | func NewChangeTeamService(p *packet.PacketData, client net.Conn) ChangeTeamService { 25 | return &changeTeamServiceImpl{ 26 | team: utils.ReadUint8(p.Data, &p.CurOffset), 27 | client: client, 28 | } 29 | } 30 | 31 | func (c *changeTeamServiceImpl) Handle(ctx context.Context) error { 32 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 33 | if u == nil || u.CurrentRoomId == 0 { 34 | return errors.New("can't find user or user not in room") 35 | } 36 | 37 | room, err := client.GetRoomClient().GetRoomInfo(ctx, u.CurrentRoomId) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | // 设置用户Team 43 | if err := client.GetUserCacheClient().SetUserRoom(ctx, u.UserID, room.RoomId, c.team); err != nil { 44 | return errors.New("set user room failed") 45 | } 46 | 47 | out_packet := out.BuildChangTeam(u.UserID, c.team) 48 | for i := range room.Users { 49 | tmp_u := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 50 | if tmp_u == nil || tmp_u.CurrentRoomId == 0 { 51 | continue 52 | } 53 | 54 | rst := utils.BytesCombine(packet.BuildHeader(tmp_u.GetNextSeq(), constant.PacketTypeRoom), out_packet) 55 | packet.SendPacket(rst, tmp_u.CurrentConnection) 56 | } 57 | 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /main_service/service/room/closeresult.go: -------------------------------------------------------------------------------- 1 | package room 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type CloseResultService interface { 16 | Handle(ctx context.Context) error 17 | } 18 | 19 | type closeResultServiceImpl struct { 20 | client net.Conn 21 | } 22 | 23 | func NewCloseResultService(client net.Conn) CloseResultService { 24 | return &closeResultServiceImpl{ 25 | client: client, 26 | } 27 | } 28 | 29 | func (c *closeResultServiceImpl) Handle(ctx context.Context) error { 30 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 31 | if u == nil || u.CurrentRoomId == 0 { 32 | return errors.New("can't find user or user not in room") 33 | } 34 | 35 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeHost), out.BuildCloseResultWindow()) 36 | packet.SendPacket(rst, u.CurrentConnection) 37 | 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /main_service/service/room/join.go: -------------------------------------------------------------------------------- 1 | package room 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/main_service/model/user" 13 | "github.com/KouKouChan/YuriCore/utils" 14 | ) 15 | 16 | type JoinRoomService interface { 17 | Handle(ctx context.Context) error 18 | } 19 | 20 | type joinRoomServiceImpl struct { 21 | roomID uint16 22 | password string 23 | client net.Conn 24 | } 25 | 26 | func NewJoinRoomService(p *packet.PacketData, client net.Conn) JoinRoomService { 27 | return &joinRoomServiceImpl{ 28 | roomID: utils.ReadUint16(p.Data, &p.CurOffset), 29 | password: utils.ReadStringToNULL(p.Data, &p.CurOffset), 30 | client: client, 31 | } 32 | } 33 | 34 | func (j *joinRoomServiceImpl) Handle(ctx context.Context) error { 35 | u := client.GetUserCacheClient().GetUserByConnection(ctx, j.client) 36 | if u == nil { 37 | return errors.New("can't find user") 38 | } 39 | 40 | // 房间 41 | if j.roomID == 0 { 42 | return errors.New("the room which user want to join is illegal") 43 | 44 | } 45 | 46 | // 判断用户房间 47 | if u.CurrentRoomId > 0 { 48 | NewLeaveRoomService(j.client).UserRoomEnd(ctx, u) 49 | client.GetUserCacheClient().QuitUserRoom(ctx, u.UserID) 50 | return errors.New("user try to join room but already in another room") 51 | 52 | } 53 | 54 | room, err := client.GetRoomClient().JoinRoom(ctx, u.UserID, j.roomID) 55 | if err != nil { 56 | return err 57 | } 58 | 59 | // TODO检索房间状态、密码、加入的team等 60 | if room.PassWd != "" && room.PassWd != j.password { 61 | out.OnSendMessage(u.GetNextSeq(), u.CurrentConnection, constant.MessageDialogBox, constant.CSO_Warning_ROOM_JOIN_FAILED_INVALID_PASSWD) 62 | return nil 63 | } 64 | 65 | // 获取用户信息 66 | info, err := client.GetUserClient().GetUserInfo(ctx, u.UserID) 67 | if err != nil { 68 | return err 69 | } 70 | 71 | if info == nil || info.UserID == 0 { 72 | return errors.New("get null user for join room") 73 | } 74 | 75 | // 设置用户房间ID 76 | if err := client.GetUserCacheClient().SetUserRoom(ctx, u.UserID, room.RoomId, constant.UserForceTerrorist); err != nil { 77 | return errors.New("set user room failed") 78 | } 79 | if err := client.GetUserCacheClient().SetUserStatus(ctx, u.UserID, constant.UserNotReady); err != nil { 80 | return errors.New("set user room failed") 81 | } 82 | if err := client.GetUserCacheClient().SetUserIngame(ctx, u.UserID, false); err != nil { 83 | return errors.New("set user not in game failed") 84 | } 85 | if err := client.GetUserCacheClient().FlushUserRoomData(ctx, u.UserID, []byte{}); err != nil { 86 | return errors.New("clear user data failed") 87 | } 88 | 89 | info.NetInfo = u.NetInfo 90 | 91 | infos := []*user.UserInfo{} 92 | caches := []*user.UserCache{} 93 | 94 | uplayjoin := out.BuildPlayerJoin(u, info) 95 | ustatus := out.BuildUserReadyStatus(u.UserID, u.Currentstatus) 96 | uteam := out.BuildChangTeam(u.UserID, u.CurrentTeam) 97 | for i := 0; i < len(room.Users); i++ { 98 | player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 99 | if player == nil { 100 | continue 101 | } 102 | caches = append(caches, player) 103 | 104 | player_info, err := client.GetUserClient().GetUserInfo(ctx, room.Users[i]) 105 | if err != nil { 106 | return err 107 | } 108 | if player_info == nil { 109 | continue 110 | } 111 | 112 | infos = append(infos, player_info) 113 | 114 | if player.UserID != u.UserID { 115 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoom), uplayjoin) 116 | packet.SendPacket(rst, player.CurrentConnection) 117 | rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoom), ustatus) 118 | packet.SendPacket(rst, player.CurrentConnection) 119 | rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoom), uteam) 120 | packet.SendPacket(rst, player.CurrentConnection) 121 | } 122 | } 123 | 124 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeRoom), out.BuildCreateRoom(infos, caches, room)) 125 | packet.SendPacket(rst, u.CurrentConnection) 126 | 127 | return nil 128 | } 129 | -------------------------------------------------------------------------------- /main_service/service/room/new.go: -------------------------------------------------------------------------------- 1 | package room 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/main_service/model/server" 13 | "github.com/KouKouChan/YuriCore/main_service/model/user" 14 | "github.com/KouKouChan/YuriCore/utils" 15 | ) 16 | 17 | type CreateRoomService interface { 18 | Handle(ctx context.Context) error 19 | } 20 | 21 | type createRoomServiceImpl struct { 22 | roomName string 23 | GameModeID uint8 24 | maxPlayers uint8 25 | unk01 uint8 26 | WinLimit uint8 27 | unk03 uint8 28 | KillLimit uint16 29 | TimeLimit uint8 30 | unk05 uint8 31 | client net.Conn 32 | } 33 | 34 | func NewCreateRoomService(p *packet.PacketData, client net.Conn) CreateRoomService { 35 | return &createRoomServiceImpl{ 36 | roomName: string(utils.ReadStringToNULL(p.Data, &p.CurOffset)), 37 | GameModeID: utils.ReadUint8(p.Data, &p.CurOffset), 38 | maxPlayers: utils.ReadUint8(p.Data, &p.CurOffset), 39 | unk01: utils.ReadUint8(p.Data, &p.CurOffset), 40 | WinLimit: utils.ReadUint8(p.Data, &p.CurOffset), 41 | unk03: utils.ReadUint8(p.Data, &p.CurOffset), 42 | KillLimit: utils.ReadUint16(p.Data, &p.CurOffset), 43 | TimeLimit: utils.ReadUint8(p.Data, &p.CurOffset), 44 | unk05: utils.ReadUint8(p.Data, &p.CurOffset), 45 | client: client, 46 | } 47 | } 48 | 49 | func (c *createRoomServiceImpl) Handle(ctx context.Context) error { 50 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 51 | if u == nil { 52 | return errors.New("can't find user") 53 | } 54 | 55 | // 判断用户房间 56 | if u.CurrentRoomId > 0 { 57 | NewLeaveRoomService(c.client).UserRoomEnd(ctx, u) 58 | client.GetUserCacheClient().QuitUserRoom(ctx, u.UserID) 59 | return errors.New("user try to create room but already in another room") 60 | 61 | } 62 | 63 | room, err := client.GetRoomClient().NewRoom( 64 | ctx, 65 | &server.Room{ 66 | RoomId: 0, 67 | RoomNumber: 0, 68 | HostUserID: u.UserID, 69 | HostUserName: u.NickName, 70 | CanSpec: 0, 71 | IsVipRoom: 0, 72 | VipRoomLevel: 0, 73 | RoomName: c.roomName, 74 | PassWd: "", 75 | GameModeID: c.GameModeID, 76 | MapID: 1, 77 | MaxPlayers: c.maxPlayers, 78 | WinLimit: c.WinLimit, 79 | KillLimit: c.KillLimit, 80 | WeaponRestrictions: 0, 81 | Status: constant.StatusWaiting, 82 | TeamBalanceType: 0, 83 | AreBotsEnabled: 0, 84 | BotDifficulty: 0, 85 | NumCtBots: 0, 86 | NumTrBots: 0, 87 | StartMoney: 7500, 88 | ChangeTeams: 1, 89 | RespawnTime: 3, 90 | NextMapEnabled: 0, 91 | Difficulty: 0, 92 | IsIngame: 0, 93 | Users: []uint32{u.UserID}, 94 | ParentChannelServer: u.CurrentServerIndex, 95 | ParentChannel: u.CurrentChannelIndex, 96 | GameTime: c.TimeLimit, 97 | GameTimePerRound: 2, 98 | EnableVoice: 1, 99 | ShowFlash: 1, 100 | LevelLimit: 2, 101 | BuyLimitTime: 90, 102 | }, 103 | ) 104 | if err != nil { 105 | return err 106 | } 107 | 108 | // 获取用户信息 109 | info, err := client.GetUserClient().GetUserInfo(ctx, u.UserID) 110 | if err != nil { 111 | return err 112 | } 113 | 114 | if info == nil || info.UserID == 0 { 115 | return errors.New("get null user for create room") 116 | } 117 | 118 | // 设置用户房间ID 119 | if err := client.GetUserCacheClient().SetUserRoom(ctx, u.UserID, room.RoomId, constant.UserForceCounterTerrorist); err != nil { 120 | return errors.New("set user room failed") 121 | } 122 | if err := client.GetUserCacheClient().SetUserStatus(ctx, u.UserID, constant.UserNotReady); err != nil { 123 | return errors.New("set user room failed") 124 | } 125 | if err := client.GetUserCacheClient().SetUserIngame(ctx, u.UserID, false); err != nil { 126 | return errors.New("set user not in game failed") 127 | } 128 | if err := client.GetUserCacheClient().FlushUserRoomData(ctx, u.UserID, []byte{}); err != nil { 129 | return errors.New("clear user data failed") 130 | } 131 | 132 | info.NetInfo = u.NetInfo 133 | 134 | infos := []*user.UserInfo{info} 135 | caches := []*user.UserCache{u} 136 | 137 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeRoom), out.BuildCreateRoom(infos, caches, room)) 138 | packet.SendPacket(rst, u.CurrentConnection) 139 | 140 | // 发送新房间 141 | addroom := out.BuildAddChannelRoom(room, true, 0xFFFFFFFF) 142 | userIDs := client.GetUserCacheClient().GetChannelNoRoomUsers(ctx, u.CurrentServerIndex, u.CurrentChannelIndex) 143 | for i := range userIDs { 144 | if userIDs[i] == u.UserID { 145 | continue 146 | } 147 | 148 | player := client.GetUserCacheClient().GetUserByID(ctx, userIDs[i]) 149 | if player == nil { 150 | continue 151 | } 152 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoomList), addroom) 153 | packet.SendPacket(rst, player.CurrentConnection) 154 | } 155 | return nil 156 | } 157 | -------------------------------------------------------------------------------- /main_service/service/room/ready.go: -------------------------------------------------------------------------------- 1 | package room 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | . "github.com/KouKouChan/YuriCore/verbose" 14 | ) 15 | 16 | type ReadyService interface { 17 | Handle(ctx context.Context) error 18 | } 19 | 20 | type readyServiceImpl struct { 21 | Unk00 uint8 22 | client net.Conn 23 | } 24 | 25 | func NewReadyService(p *packet.PacketData, client net.Conn) ReadyService { 26 | return &readyServiceImpl{ 27 | Unk00: utils.ReadUint8(p.Data, &p.CurOffset), 28 | client: client, 29 | } 30 | } 31 | 32 | func (c *readyServiceImpl) Handle(ctx context.Context) error { 33 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 34 | if u == nil || u.CurrentRoomId == 0 { 35 | return errors.New("can't find user or user not in room") 36 | } 37 | 38 | room, err := client.GetRoomClient().GetRoomInfo(ctx, u.CurrentRoomId) 39 | if err != nil { 40 | return err 41 | } 42 | 43 | //设置新的状态 44 | if u.Currentstatus == constant.UserReady { 45 | if err = client.GetUserCacheClient().SetUserStatus(ctx, u.UserID, constant.UserNotReady); err != nil { 46 | return nil 47 | } 48 | DebugInfo(1, "User", u.UserName, "unreadied in room", room.RoomName, "id", room.RoomId) 49 | } else { 50 | if err = client.GetUserCacheClient().SetUserStatus(ctx, u.UserID, constant.UserReady); err != nil { 51 | return nil 52 | } 53 | DebugInfo(1, "User", u.UserName, "readied in room", room.RoomName, "id", room.RoomId) 54 | } 55 | 56 | // 发送数据包 57 | ustatus := out.BuildUserReadyStatus(u.UserID, u.Currentstatus) 58 | for i := range room.Users { 59 | dest_player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 60 | if dest_player == nil { 61 | continue 62 | } 63 | rst := utils.BytesCombine(packet.BuildHeader(dest_player.GetNextSeq(), constant.PacketTypeRoom), ustatus) 64 | packet.SendPacket(rst, dest_player.CurrentConnection) 65 | } 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /main_service/service/room/start.go: -------------------------------------------------------------------------------- 1 | package room 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type StartService interface { 16 | Handle(ctx context.Context) error 17 | } 18 | 19 | type startServiceImpl struct { 20 | client net.Conn 21 | } 22 | 23 | func NewStartService(client net.Conn) StartService { 24 | return &startServiceImpl{ 25 | client: client, 26 | } 27 | } 28 | 29 | func (c *startServiceImpl) Handle(ctx context.Context) error { 30 | u := client.GetUserCacheClient().GetUserByConnection(ctx, c.client) 31 | if u == nil { 32 | return errors.New("can't find user") 33 | } 34 | 35 | // 判断用户房间 36 | if u.CurrentRoomId == 0 { 37 | return errors.New("user try to start game but not in room") 38 | } 39 | 40 | room, err := client.GetRoomClient().GetRoomInfo(ctx, u.CurrentRoomId) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | client.GetUserCacheClient().ResetAssistNum(ctx, u.UserID) 46 | client.GetUserCacheClient().ResetDeadNum(ctx, u.UserID) 47 | client.GetUserCacheClient().ResetKillNum(ctx, u.UserID) 48 | client.GetUserCacheClient().SetUserIngame(ctx, u.UserID, true) 49 | // 给所有玩家发送他的状态 50 | temp := out.BuildUserReadyStatus(u.UserID, u.Currentstatus) 51 | for i := range room.Users { 52 | player := client.GetUserCacheClient().GetUserByID(ctx, room.Users[i]) 53 | if player == nil { 54 | continue 55 | } 56 | rst := utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeRoom), temp) 57 | packet.SendPacket(rst, player.CurrentConnection) 58 | } 59 | 60 | if room.HostUserID == u.UserID { 61 | // 修改房间状态 62 | room, err = client.GetRoomClient().StartGame(ctx, u.UserID, u.CurrentRoomId) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | // 房主开始游戏 68 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeHost), out.BuildStartRoom(room.HostUserID)) 69 | packet.SendPacket(rst, u.CurrentConnection) 70 | return nil 71 | } 72 | 73 | host := client.GetUserCacheClient().GetUserByID(ctx, room.HostUserID) 74 | if host == nil { 75 | client.GetUserCacheClient().SetUserIngame(ctx, u.UserID, false) 76 | return errors.New("can't find host") 77 | } 78 | 79 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeHost), out.BuildConnectHost(host.NetInfo.ExternalIpAddress, 27005)) 80 | packet.SendPacket(rst, u.CurrentConnection) 81 | 82 | return nil 83 | } 84 | -------------------------------------------------------------------------------- /main_service/service/roomlist/roomlist.go: -------------------------------------------------------------------------------- 1 | package roomlist 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/main_service/model/user" 13 | "github.com/KouKouChan/YuriCore/utils" 14 | ) 15 | 16 | type RoomListService interface { 17 | Handler(ctx context.Context) error 18 | } 19 | 20 | type roomListServiceImpl struct { 21 | serverIndex uint8 22 | channelIndex uint8 23 | client net.Conn 24 | } 25 | 26 | func NewRoomListService(serverIndex, channelIndex uint8, client net.Conn) RoomListService { 27 | return &roomListServiceImpl{ 28 | serverIndex: serverIndex, 29 | channelIndex: channelIndex, 30 | client: client, 31 | } 32 | } 33 | 34 | func (r *roomListServiceImpl) Handler(ctx context.Context) error { 35 | u := client.GetUserCacheClient().GetUserByConnection(ctx, r.client) 36 | if u == nil { 37 | return errors.New("can't find user") 38 | } 39 | 40 | u_info, err := client.GetUserClient().GetUserInfo(ctx, u.UserID) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | if u_info == nil || u_info.UserID == 0 { 46 | return errors.New("get null user for join lobby") 47 | } 48 | 49 | //设置用户所在频道 50 | if err := client.GetUserCacheClient().SetUserChannel(ctx, u.UserID, r.serverIndex, r.channelIndex); err != nil { 51 | return errors.New("set user channel failed") 52 | } 53 | 54 | // RoomList部分 55 | rooms, err := client.GetRoomClient().GetRoomList(ctx, r.serverIndex, r.channelIndex) 56 | if err != nil { 57 | return err 58 | } 59 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeRoomList), out.BuildRoomList(rooms)) 60 | packet.SendPacket(rst, u.CurrentConnection) 61 | 62 | // 找到所有用户 63 | users := []user.UserInfo{} 64 | userIDs := client.GetUserCacheClient().GetChannelUsers(ctx, r.serverIndex, r.channelIndex) 65 | for i := range userIDs { 66 | info, err := client.GetUserClient().GetUserInfo(ctx, userIDs[i]) 67 | if err != nil { 68 | return err 69 | } 70 | users = append(users, *info) 71 | } 72 | 73 | // lobby 74 | lobbyreply := out.BuildLobbyReply(users) 75 | lobbyJoin := out.BuildLobbyJoin(u_info) 76 | for i := range userIDs { 77 | if userIDs[i] == u.UserID { 78 | rst = utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeLobby), lobbyreply) 79 | packet.SendPacket(rst, u.CurrentConnection) 80 | continue 81 | } 82 | 83 | player := client.GetUserCacheClient().GetUserByID(ctx, userIDs[i]) 84 | if player == nil { 85 | continue 86 | } 87 | rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeLobby), lobbyJoin) 88 | packet.SendPacket(rst, player.CurrentConnection) 89 | } 90 | 91 | return nil 92 | } 93 | -------------------------------------------------------------------------------- /main_service/service/serverlist/serverlist.go: -------------------------------------------------------------------------------- 1 | package serverlist 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/client" 9 | "github.com/KouKouChan/YuriCore/main_service/constant" 10 | "github.com/KouKouChan/YuriCore/main_service/model/out" 11 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 12 | "github.com/KouKouChan/YuriCore/utils" 13 | ) 14 | 15 | type ServerListService interface { 16 | Handler(ctx context.Context) error 17 | } 18 | 19 | type serverListServiceImpl struct { 20 | client net.Conn 21 | } 22 | 23 | func NewServerListService(client net.Conn) ServerListService { 24 | return &serverListServiceImpl{ 25 | client: client, 26 | } 27 | } 28 | 29 | func (s *serverListServiceImpl) Handler(ctx context.Context) error { 30 | u := client.GetUserCacheClient().GetUserByConnection(ctx, s.client) 31 | if u == nil { 32 | return errors.New("can't find user") 33 | } 34 | 35 | // Server 36 | servers, err := client.GetRoomClient().GetServiceList(ctx) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | //设置用户所在频道 42 | srvID := u.CurrentServerIndex 43 | chlID := u.CurrentChannelIndex 44 | if err := client.GetUserCacheClient().SetUserQuitChannel(ctx, u.UserID); err != nil { 45 | return errors.New("set quit channel failed") 46 | } 47 | 48 | rst := utils.BytesCombine(packet.BuildHeader(u.GetNextSeq(), constant.PacketTypeServerList), out.BuildServerList(servers)) 49 | packet.SendPacket(rst, u.CurrentConnection) 50 | 51 | if srvID == 0 || chlID == 0 { 52 | return nil 53 | } 54 | // 找到所有用户 55 | userIDs := client.GetUserCacheClient().GetChannelUsers(ctx, srvID, chlID) 56 | 57 | // lobby 58 | lobbyleave := out.BuildLobbyLeave(u.UserID) 59 | for i := range userIDs { 60 | player := client.GetUserCacheClient().GetUserByID(ctx, userIDs[i]) 61 | if player == nil { 62 | continue 63 | } 64 | rst = utils.BytesCombine(packet.BuildHeader(player.GetNextSeq(), constant.PacketTypeLobby), lobbyleave) 65 | packet.SendPacket(rst, player.CurrentConnection) 66 | } 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /main_service/service/udp/udp.go: -------------------------------------------------------------------------------- 1 | package udp 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/client" 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | ) 9 | 10 | type UpdateUDPService interface { 11 | Handle(ctx context.Context) (uint16, error) 12 | } 13 | 14 | type updateUDPServiceImpl struct { 15 | portId uint16 16 | localPort uint16 17 | externalPort uint16 18 | externalIPAddress uint32 19 | localIpAddress uint32 20 | 21 | user *user.UserCache 22 | } 23 | 24 | func GetUpdateUDPService(portId uint16, localPort uint16, externalPort uint16, externalIPAddress, localIpAddress uint32, user *user.UserCache) UpdateUDPService { 25 | update := updateUDPServiceImpl{ 26 | portId: portId, 27 | localPort: localPort, 28 | externalPort: externalPort, 29 | externalIPAddress: externalIPAddress, 30 | localIpAddress: localIpAddress, 31 | user: user, 32 | } 33 | 34 | return &update 35 | } 36 | 37 | func (r *updateUDPServiceImpl) Handle(ctx context.Context) (uint16, error) { 38 | return client.GetUserCacheClient().FlushUserUDP(ctx, r.user.UserID, r.portId, r.localPort, r.externalPort, r.externalIPAddress, r.localIpAddress) 39 | } 40 | -------------------------------------------------------------------------------- /main_service/service/version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | -------------------------------------------------------------------------------- /main_service/start/config.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "math" 5 | 6 | "github.com/KouKouChan/YuriCore/conf" 7 | "github.com/KouKouChan/YuriCore/main_service/client" 8 | "github.com/KouKouChan/YuriCore/main_service/infrastructure/config" 9 | "github.com/KouKouChan/YuriCore/verbose" 10 | ) 11 | 12 | func initConfig(exePath string) { 13 | conf.Config.InitConf(exePath + "/server.conf") 14 | if conf.Config.MaxUsers <= 0 { 15 | conf.Config.MaxUsers = math.MaxUint32 16 | } 17 | verbose.Level = conf.Config.DebugLevel 18 | verbose.LogFile = conf.Config.LogFile 19 | if conf.Config.LogFile != 0 { 20 | verbose.InitLoger(exePath, "yuricore.log") 21 | } 22 | 23 | client.InitConfigClient(config.NewConfigImpl()) 24 | } 25 | -------------------------------------------------------------------------------- /main_service/start/init.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/conf" 5 | "github.com/KouKouChan/YuriCore/utils" 6 | ) 7 | 8 | func Init(exePath string) { 9 | initConfig(exePath) 10 | utils.InitConverter(conf.Config.CodePage) 11 | initUserService() 12 | initUserCache() 13 | initRoomService() 14 | } 15 | -------------------------------------------------------------------------------- /main_service/start/room_service.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/KouKouChan/YuriCore/conf" 7 | "github.com/KouKouChan/YuriCore/main_service/client" 8 | "github.com/KouKouChan/YuriCore/main_service/infrastructure/room_service" 9 | ) 10 | 11 | func initRoomService() { 12 | client.InitRoomClient(room_service.NewRoomServiceImpl(fmt.Sprintf("%s:%d", conf.Config.RoomAdress, conf.Config.RoomPort))) 13 | } 14 | -------------------------------------------------------------------------------- /main_service/start/user_cache.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/main_service/client" 5 | "github.com/KouKouChan/YuriCore/main_service/infrastructure/user_cache" 6 | ) 7 | 8 | func initUserCache() { 9 | client.InitUserCacheClient(user_cache.NewUserCacheImpl()) 10 | } 11 | -------------------------------------------------------------------------------- /main_service/start/user_service.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/KouKouChan/YuriCore/conf" 7 | "github.com/KouKouChan/YuriCore/main_service/client" 8 | "github.com/KouKouChan/YuriCore/main_service/infrastructure/user_service" 9 | ) 10 | 11 | func initUserService() { 12 | client.InitUserClient(user_service.NewUserService(fmt.Sprintf("%s:%d", conf.Config.UserAdress, conf.Config.UserPort))) 13 | } 14 | -------------------------------------------------------------------------------- /main_service/tcp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | "strconv" 8 | 9 | "github.com/KouKouChan/YuriCore/conf" 10 | "github.com/KouKouChan/YuriCore/main_service/constant" 11 | "github.com/KouKouChan/YuriCore/main_service/controller" 12 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 13 | . "github.com/KouKouChan/YuriCore/verbose" 14 | ) 15 | 16 | func initTCP() { 17 | defer func() { 18 | if err := recover(); err != nil { 19 | fmt.Println("TCP server suffered a fault !") 20 | fmt.Println("error:", err) 21 | fmt.Println("Fault end!") 22 | } 23 | }() 24 | 25 | server, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.Config.MainPort)) 26 | if err != nil { 27 | fmt.Println("Init tcp socket error !\n") 28 | panic(err) 29 | } 30 | defer server.Close() 31 | 32 | fmt.Println("Server is running at", "[AnyAdapter]:"+strconv.Itoa(int(conf.Config.MainPort))) 33 | for { 34 | client, err := server.Accept() 35 | if err != nil { 36 | DebugInfo(2, "Server accept data error !\n") 37 | continue 38 | } 39 | DebugInfo(2, "Server accept a new connection request at", client.RemoteAddr().String()) 40 | client.Write([]byte("~SERVERCONNECTED\n")) 41 | go RecvMessage(client) 42 | } 43 | } 44 | 45 | //RecvMessage 循环处理收到的包 46 | func RecvMessage(client net.Conn) { 47 | var dataPacket packet.PacketData 48 | var seq uint8 49 | packetController := controller.NewPacketController() 50 | 51 | defer client.Close() //关闭con 52 | defer func() { 53 | if err := recover(); err != nil { 54 | fmt.Println("Client", client.RemoteAddr().String(), "suffered a fault !") 55 | fmt.Println(err) 56 | fmt.Println("dump data", dataPacket.Data, "offset:", dataPacket.CurOffset) 57 | fmt.Println("Fault end!") 58 | controller.GetDisconnectController(client).Handle(context.TODO()) 59 | } 60 | }() 61 | for { 62 | //读取4字节数据包头部 63 | headBytes, err := packetController.ReadHead(client) 64 | if err != nil { 65 | goto close 66 | } 67 | header := packetController.GetHeadPacket(headBytes) 68 | //读取数据部分 69 | databytes, err := packetController.ReadData(client, header.Length) 70 | if err != nil { 71 | goto close 72 | } 73 | dataPacket = packetController.GetDataPacket(header, databytes) 74 | 75 | DebugPrintf(2, "data packet %+v from %s", dataPacket, client.RemoteAddr().String()) 76 | //执行功能 77 | switch dataPacket.Id { 78 | case constant.PacketTypeLogin: 79 | err = controller.GetLoginController(client, &dataPacket, &seq).Handle(context.TODO()) 80 | case constant.PacketTypeRegister: 81 | err = controller.GetRegisterController(client, &dataPacket, &seq).Handle(context.TODO()) 82 | case constant.PacketTypeNewCharacter: 83 | err = controller.GetNewCharacter(client, &dataPacket, &seq).Handle(context.TODO()) 84 | case constant.PacketTypeChat: 85 | err = controller.GetChatController(client, &dataPacket).Handle(context.TODO()) 86 | case constant.PacketTypeRequestChannels: 87 | err = controller.GetServerListController(client).Handle(context.TODO()) 88 | case constant.PacketTypeRequestRoomList: 89 | err = controller.GetRoomListController(&dataPacket, client).Handle(context.TODO()) 90 | case constant.PacketTypeRoom: 91 | err = controller.GetRoomController(&dataPacket, client).Handle(context.TODO()) 92 | case constant.PacketTypeVersion: 93 | err = controller.GetVersionController(&dataPacket, client).Handle() 94 | case constant.PacketTypeFavorite: 95 | err = controller.GetFavorateController(&dataPacket, client).Handle(context.TODO()) 96 | case constant.PacketTypePlayerInfo: 97 | err = controller.GetPlayerInfoController(&dataPacket, client).Handle(context.TODO()) 98 | case constant.PacketTypeHost: 99 | err = controller.GetHostController(&dataPacket, client).Handle(context.TODO()) 100 | case constant.PacketTypeOption: 101 | err = controller.GetOptionController(&dataPacket, client).Handle(context.TODO()) 102 | default: 103 | DebugInfo(2, "Unknown packet", dataPacket.Id, "from", client.RemoteAddr().String()) 104 | } 105 | if err != nil { 106 | DebugInfo(2, "handle packet ID=", dataPacket.Id, "failed ! error=", err) 107 | } 108 | } 109 | 110 | close: 111 | controller.GetDisconnectController(client).Handle(context.TODO()) 112 | DebugInfo(1, "client", client.RemoteAddr().String(), "closed the connection") 113 | } 114 | -------------------------------------------------------------------------------- /main_service/udp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | "strconv" 8 | 9 | "github.com/KouKouChan/YuriCore/conf" 10 | "github.com/KouKouChan/YuriCore/main_service/client" 11 | "github.com/KouKouChan/YuriCore/main_service/controller" 12 | "github.com/KouKouChan/YuriCore/main_service/model/out" 13 | "github.com/KouKouChan/YuriCore/main_service/model/packet" 14 | "github.com/KouKouChan/YuriCore/utils" 15 | . "github.com/KouKouChan/YuriCore/verbose" 16 | ) 17 | 18 | func initUDP() { 19 | udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", conf.Config.MainPort)) 20 | if err != nil { 21 | fmt.Println("Init udp addr error !\n") 22 | panic(err) 23 | } 24 | holepunchserver, err := net.ListenUDP("udp", udpAddr) 25 | if err != nil { 26 | fmt.Println("Init udp socket error !\n") 27 | panic(err) 28 | } 29 | defer holepunchserver.Close() 30 | StartHolePunchServer(strconv.Itoa(int(conf.Config.MainPort)), holepunchserver) 31 | } 32 | 33 | func StartHolePunchServer(port string, server *net.UDPConn) { 34 | defer server.Close() 35 | defer func() { 36 | if err := recover(); err != nil { 37 | fmt.Println("UDP server suffered a fault !") 38 | fmt.Println("error:", err) 39 | fmt.Println("Fault end!") 40 | } 41 | }() 42 | fmt.Println("Server UDPholepunch is running at", "[AnyAdapter]:"+port) 43 | for { 44 | data := make([]byte, 1024) 45 | n, ClientAddr, err := server.ReadFromUDP(data) 46 | if err != nil { 47 | DebugInfo(2, "UDP read error from", ClientAddr.String()) 48 | continue 49 | } 50 | go RecvHolePunchMessage(data[:n], n, ClientAddr, server) 51 | } 52 | } 53 | 54 | //RecvHolePunchMessage 处理收到的包 55 | func RecvHolePunchMessage(data []byte, len int, UDPClient *net.UDPAddr, server *net.UDPConn) { 56 | defer func() { 57 | if err := recover(); err != nil { 58 | fmt.Println("Recv UDP packet suffered a fault !") 59 | fmt.Println(err) 60 | fmt.Println("Fault end!") 61 | return 62 | } 63 | }() 64 | //分析数据包 65 | var p packet.InUDPmsg 66 | if !p.PraseUDPpacket(data, len) { 67 | DebugInfo(2, "UDP had a illegal packet from", UDPClient.String()) 68 | return 69 | } 70 | if p.IsHeartbeat() { 71 | return 72 | } 73 | cliadr := UDPClient.IP.To4().String() 74 | externalIPAddress, err := utils.IPToUint32(cliadr) 75 | if err != nil { 76 | DebugInfo(2, "Error : Prasing externalIpAddress error !") 77 | return 78 | } 79 | //找到对应玩家 80 | uPtr := client.GetUserCacheClient().GetUserByID(context.TODO(), p.UserId) 81 | if uPtr == nil || 82 | uPtr.UserID <= 0 { 83 | return 84 | } 85 | //更新netinfo 86 | index, err := controller.GetUpdateUDPController(p.PortId, p.Port, uint16(UDPClient.Port), externalIPAddress, p.IpAddress, uPtr).Handle(context.TODO()) 87 | if index == 0xFF || err != nil { 88 | return 89 | } 90 | 91 | //发送返回数据 92 | rst := out.BuildUDPHolepunch(index) 93 | server.WriteToUDP(rst, UDPClient) 94 | } 95 | -------------------------------------------------------------------------------- /room_service/client/room_table.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | ) 9 | 10 | type RoomTable interface { 11 | AddRoom(ctx context.Context, data *server.Room) (*server.Room, error) 12 | UpdateRoom(ctx context.Context, data *server.Room) error 13 | DeleteRoom(ctx context.Context, roomid uint16) error 14 | GetRoomList(ctx context.Context, serverID, ChannelID uint8) ([]server.Room, error) 15 | GetServerList(ctx context.Context) ([]server.Server, error) 16 | AddServer(ctx context.Context, srv server.Server) 17 | AddChannel(ctx context.Context, serverID uint8, chl server.Channel) 18 | GetRoomInfo(ctx context.Context, roomID uint16) (*server.Room, error) 19 | UpdateRoomSafe(ctx context.Context, data *server.Room) error 20 | AddUser(ctx context.Context, roomID uint16, userID uint32) (*server.Room, error) 21 | LeaveUser(ctx context.Context, roomID uint16, userID uint32) (*server.Room, error) 22 | SetUserHost(ctx context.Context, roomID uint16, userID uint32, name string) (*server.Room, error) 23 | StartGame(ctx context.Context, roomID uint16, userID uint32) (*server.Room, error) 24 | EndGame(ctx context.Context, roomID uint16, userID uint32) (*server.Room, error) 25 | } 26 | 27 | var ( 28 | roomTableClient RoomTable 29 | roomTableOnce sync.Once 30 | ) 31 | 32 | func GetRoomTableClient() RoomTable { 33 | return roomTableClient 34 | } 35 | 36 | func InitRoomTableClient(client RoomTable) { 37 | roomTableOnce.Do( 38 | func() { 39 | roomTableClient = client 40 | }, 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /room_service/controller/delroom.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/room_service/service" 8 | ) 9 | 10 | type DelRoomController interface { 11 | Handle(ctx context.Context) error 12 | } 13 | 14 | type delRoomControllerImpl struct { 15 | roomID uint16 16 | } 17 | 18 | func NewDelRoomController(roomID uint16) DelRoomController { 19 | return &delRoomControllerImpl{ 20 | roomID: roomID, 21 | } 22 | } 23 | 24 | func (d *delRoomControllerImpl) Handle(ctx context.Context) error { 25 | if d.roomID == 0 { 26 | return errors.New("wrong roomid") 27 | } 28 | 29 | return service.NewDelRoomService(d.roomID).Handle(ctx) 30 | } 31 | -------------------------------------------------------------------------------- /room_service/controller/endgame.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | "github.com/KouKouChan/YuriCore/room_service/service" 9 | ) 10 | 11 | type EndGameController interface { 12 | Handle(ctx context.Context) (*server.Room, error) 13 | } 14 | 15 | type endGameControllerImpl struct { 16 | roomID uint16 17 | userID uint32 18 | } 19 | 20 | func NewEndGameController(roomID uint16, userID uint32) EndGameController { 21 | return &endGameControllerImpl{ 22 | roomID: roomID, 23 | userID: userID, 24 | } 25 | } 26 | 27 | func (l *endGameControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 28 | if l.roomID == 0 || l.userID == 0 { 29 | return nil, errors.New("wrong userid or roomid") 30 | } 31 | 32 | return service.NewEndService(l.roomID, l.userID).Handle(ctx) 33 | } 34 | -------------------------------------------------------------------------------- /room_service/controller/getroom.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/service" 8 | ) 9 | 10 | type GetRoomInfoController interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type getRoomInfoControllerImpl struct { 15 | roomID uint16 16 | } 17 | 18 | func NewGetRoomInfoController(roomID uint16) GetRoomInfoController { 19 | return &getRoomInfoControllerImpl{ 20 | roomID: roomID, 21 | } 22 | } 23 | 24 | func (g *getRoomInfoControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 25 | 26 | return service.NewGetRoomInfoService(g.roomID).Handle(ctx) 27 | } 28 | -------------------------------------------------------------------------------- /room_service/controller/joinroom.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | "github.com/KouKouChan/YuriCore/room_service/service" 9 | ) 10 | 11 | type JoinRoomInfoController interface { 12 | Handle(ctx context.Context) (*server.Room, error) 13 | } 14 | 15 | type joinRoomInfoControllerImpl struct { 16 | roomID uint16 17 | userID uint32 18 | } 19 | 20 | func NewJoinRoomInfoController(roomID uint16, userID uint32) JoinRoomInfoController { 21 | return &joinRoomInfoControllerImpl{ 22 | roomID: roomID, 23 | userID: userID, 24 | } 25 | } 26 | 27 | func (l *joinRoomInfoControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 28 | if l.roomID == 0 || l.userID == 0 { 29 | return nil, errors.New("wrong userid or roomid") 30 | } 31 | 32 | return service.NewJoinService(l.roomID, l.userID).Handle(ctx) 33 | } 34 | -------------------------------------------------------------------------------- /room_service/controller/leaveroom.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | "github.com/KouKouChan/YuriCore/room_service/service" 9 | ) 10 | 11 | type LeaveRoomInfoController interface { 12 | Handle(ctx context.Context) (*server.Room, error) 13 | } 14 | 15 | type leaveRoomInfoControllerImpl struct { 16 | roomID uint16 17 | userID uint32 18 | } 19 | 20 | func NewLeaveRoomInfoController(roomID uint16, userID uint32) LeaveRoomInfoController { 21 | return &leaveRoomInfoControllerImpl{ 22 | roomID: roomID, 23 | userID: userID, 24 | } 25 | } 26 | 27 | func (l *leaveRoomInfoControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 28 | if l.roomID == 0 || l.userID == 0 { 29 | return nil, errors.New("wrong userid or roomid") 30 | } 31 | 32 | return service.NewLeaveService(l.roomID, l.userID).Handle(ctx) 33 | } 34 | -------------------------------------------------------------------------------- /room_service/controller/newroom.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/service" 8 | ) 9 | 10 | type NewRoomController interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type newRoomControllerImpl struct { 15 | room server.Room 16 | } 17 | 18 | func NewNewRoomController(room server.Room) NewRoomController { 19 | return &newRoomControllerImpl{ 20 | room: room, 21 | } 22 | } 23 | 24 | func (r *newRoomControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 25 | 26 | return service.NewNewRoomService(r.room).Handle(ctx) 27 | } 28 | -------------------------------------------------------------------------------- /room_service/controller/roomlist.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | "github.com/KouKouChan/YuriCore/room_service/service" 9 | ) 10 | 11 | type RoomListController interface { 12 | Handle(ctx context.Context) ([]server.Room, error) 13 | } 14 | 15 | type roomListControllerImpl struct { 16 | serverID uint8 17 | channelID uint8 18 | } 19 | 20 | func NewRoomListController(serverID, channelID uint8) RoomListController { 21 | return &roomListControllerImpl{ 22 | serverID: serverID, 23 | channelID: channelID, 24 | } 25 | } 26 | 27 | func (r *roomListControllerImpl) Handle(ctx context.Context) ([]server.Room, error) { 28 | if r.channelID == 0 || r.serverID == 0 { 29 | return nil, errors.New("wrong channelID or serverID") 30 | } 31 | 32 | return service.NewRoomListService(r.serverID, r.channelID).Handle(ctx) 33 | } 34 | -------------------------------------------------------------------------------- /room_service/controller/serverlist.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/service" 8 | ) 9 | 10 | type ServerListController interface { 11 | Handle(ctx context.Context) ([]server.Server, error) 12 | } 13 | 14 | type serverListControllerImpl struct { 15 | } 16 | 17 | func NewServerListController() ServerListController { 18 | return &serverListControllerImpl{} 19 | } 20 | 21 | func (u *serverListControllerImpl) Handle(ctx context.Context) ([]server.Server, error) { 22 | 23 | return service.NewServerListService().Handle(ctx) 24 | } 25 | -------------------------------------------------------------------------------- /room_service/controller/sethost.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | "github.com/KouKouChan/YuriCore/room_service/service" 9 | ) 10 | 11 | type SetHostController interface { 12 | Handle(ctx context.Context) (*server.Room, error) 13 | } 14 | 15 | type setHostControllerImpl struct { 16 | roomID uint16 17 | userID uint32 18 | name string 19 | } 20 | 21 | func NewSetHostController(roomID uint16, userID uint32, name string) SetHostController { 22 | return &setHostControllerImpl{ 23 | roomID: roomID, 24 | userID: userID, 25 | name: name, 26 | } 27 | } 28 | 29 | func (s *setHostControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 30 | if s.roomID == 0 || s.userID == 0 { 31 | return nil, errors.New("wrong roomid or userid") 32 | } 33 | 34 | return service.NewSetHostService(s.roomID, s.userID, s.name).Handle(ctx) 35 | } 36 | -------------------------------------------------------------------------------- /room_service/controller/startgame.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | "github.com/KouKouChan/YuriCore/room_service/service" 9 | ) 10 | 11 | type StartGameController interface { 12 | Handle(ctx context.Context) (*server.Room, error) 13 | } 14 | 15 | type startGameControllerImpl struct { 16 | roomID uint16 17 | userID uint32 18 | } 19 | 20 | func NewStartGameController(roomID uint16, userID uint32) StartGameController { 21 | return &startGameControllerImpl{ 22 | roomID: roomID, 23 | userID: userID, 24 | } 25 | } 26 | 27 | func (l *startGameControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 28 | if l.roomID == 0 || l.userID == 0 { 29 | return nil, errors.New("wrong userid or roomid") 30 | } 31 | 32 | return service.NewStartService(l.roomID, l.userID).Handle(ctx) 33 | } 34 | -------------------------------------------------------------------------------- /room_service/controller/updateroom.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/server" 8 | "github.com/KouKouChan/YuriCore/room_service/service" 9 | ) 10 | 11 | type UpdateRoomController interface { 12 | Handle(ctx context.Context) (*server.Room, error) 13 | } 14 | 15 | type updateRoomControllerImpl struct { 16 | room *server.Room 17 | safe bool 18 | } 19 | 20 | func NewUpdateRoomController(room *server.Room, safe bool) UpdateRoomController { 21 | return &updateRoomControllerImpl{ 22 | room: room, 23 | safe: safe, 24 | } 25 | } 26 | 27 | func (u *updateRoomControllerImpl) Handle(ctx context.Context) (*server.Room, error) { 28 | if u.room.RoomId == 0 { 29 | return nil, errors.New("wrong room info") 30 | } 31 | 32 | if u.safe { 33 | return service.NewUpdateRoomService(u.room).UpdateRoomSafe(ctx) 34 | } 35 | 36 | return service.NewUpdateRoomService(u.room).UpdateRoom(ctx) 37 | } 38 | -------------------------------------------------------------------------------- /room_service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/KouKouChan/YuriCore/conf" 7 | "github.com/KouKouChan/YuriCore/room_service/start" 8 | "github.com/KouKouChan/YuriCore/utils" 9 | ) 10 | 11 | func main() { 12 | ExePath, err := utils.GetExePath() 13 | if err != nil { 14 | panic(err) 15 | } 16 | 17 | start.Init(ExePath) 18 | initServer(ExePath, fmt.Sprintf("%s:%d", conf.Config.RoomAdress, conf.Config.RoomPort)) 19 | } 20 | -------------------------------------------------------------------------------- /room_service/service/delroom.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/room_service/client" 7 | ) 8 | 9 | type DelRoomService interface { 10 | Handle(ctx context.Context) error 11 | } 12 | 13 | type delRoomServiceImpl struct { 14 | roomID uint16 15 | } 16 | 17 | func NewDelRoomService(roomID uint16) DelRoomService { 18 | return &delRoomServiceImpl{ 19 | roomID: roomID, 20 | } 21 | } 22 | 23 | func (g *delRoomServiceImpl) Handle(ctx context.Context) error { 24 | 25 | return client.GetRoomTableClient().DeleteRoom(ctx, g.roomID) 26 | } 27 | -------------------------------------------------------------------------------- /room_service/service/endgame.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type EndService interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type endServiceImpl struct { 15 | roomID uint16 16 | userID uint32 17 | } 18 | 19 | func NewEndService(roomID uint16, userID uint32) EndService { 20 | return &endServiceImpl{ 21 | roomID: roomID, 22 | userID: userID, 23 | } 24 | } 25 | 26 | func (l *endServiceImpl) Handle(ctx context.Context) (*server.Room, error) { 27 | return client.GetRoomTableClient().EndGame(ctx, l.roomID, l.userID) 28 | } 29 | -------------------------------------------------------------------------------- /room_service/service/getroom.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type GetRoomInfoService interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type getRoomInfoServiceImpl struct { 15 | roomID uint16 16 | } 17 | 18 | func NewGetRoomInfoService(roomID uint16) GetRoomInfoService { 19 | return &getRoomInfoServiceImpl{ 20 | roomID: roomID, 21 | } 22 | } 23 | 24 | func (g *getRoomInfoServiceImpl) Handle(ctx context.Context) (*server.Room, error) { 25 | 26 | return client.GetRoomTableClient().GetRoomInfo(ctx, g.roomID) 27 | } 28 | -------------------------------------------------------------------------------- /room_service/service/joinroom.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type JoinService interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type joinServiceImpl struct { 15 | roomID uint16 16 | userID uint32 17 | } 18 | 19 | func NewJoinService(roomID uint16, userID uint32) JoinService { 20 | return &joinServiceImpl{ 21 | roomID: roomID, 22 | userID: userID, 23 | } 24 | } 25 | 26 | func (l *joinServiceImpl) Handle(ctx context.Context) (*server.Room, error) { 27 | return client.GetRoomTableClient().AddUser(ctx, l.roomID, l.userID) 28 | } 29 | -------------------------------------------------------------------------------- /room_service/service/leaveroom.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type LeaveService interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type leaveServiceImpl struct { 15 | roomID uint16 16 | userID uint32 17 | } 18 | 19 | func NewLeaveService(roomID uint16, userID uint32) LeaveService { 20 | return &leaveServiceImpl{ 21 | roomID: roomID, 22 | userID: userID, 23 | } 24 | } 25 | 26 | func (l *leaveServiceImpl) Handle(ctx context.Context) (*server.Room, error) { 27 | return client.GetRoomTableClient().LeaveUser(ctx, l.roomID, l.userID) 28 | } 29 | -------------------------------------------------------------------------------- /room_service/service/newroom.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type NewRoomService interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type newRoomServiceImpl struct { 15 | room server.Room 16 | } 17 | 18 | func NewNewRoomService(room server.Room) NewRoomService { 19 | return &newRoomServiceImpl{ 20 | room: room, 21 | } 22 | } 23 | 24 | func (n *newRoomServiceImpl) Handle(ctx context.Context) (*server.Room, error) { 25 | 26 | return client.GetRoomTableClient().AddRoom(ctx, &n.room) 27 | } 28 | -------------------------------------------------------------------------------- /room_service/service/roomlist.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type RoomListService interface { 11 | Handle(ctx context.Context) ([]server.Room, error) 12 | } 13 | 14 | type roomListServiceImpl struct { 15 | serverID uint8 16 | channelID uint8 17 | } 18 | 19 | func NewRoomListService(serverID, channelID uint8) RoomListService { 20 | return &roomListServiceImpl{ 21 | serverID: serverID, 22 | channelID: channelID, 23 | } 24 | } 25 | 26 | func (s *roomListServiceImpl) Handle(ctx context.Context) ([]server.Room, error) { 27 | return client.GetRoomTableClient().GetRoomList(ctx, s.serverID, s.channelID) 28 | } 29 | -------------------------------------------------------------------------------- /room_service/service/serverlist.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type ServerListService interface { 11 | Handle(ctx context.Context) ([]server.Server, error) 12 | } 13 | 14 | type serverListServiceImpl struct { 15 | } 16 | 17 | func NewServerListService() ServerListService { 18 | return &serverListServiceImpl{} 19 | } 20 | 21 | func (s *serverListServiceImpl) Handle(ctx context.Context) ([]server.Server, error) { 22 | return client.GetRoomTableClient().GetServerList(ctx) 23 | } 24 | -------------------------------------------------------------------------------- /room_service/service/sethost.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type SetHostService interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type setHostServiceImpl struct { 15 | roomID uint16 16 | userID uint32 17 | name string 18 | } 19 | 20 | func NewSetHostService(roomID uint16, userID uint32, name string) SetHostService { 21 | return &setHostServiceImpl{ 22 | roomID: roomID, 23 | userID: userID, 24 | name: name, 25 | } 26 | } 27 | 28 | func (s *setHostServiceImpl) Handle(ctx context.Context) (*server.Room, error) { 29 | 30 | return client.GetRoomTableClient().SetUserHost(ctx, s.roomID, s.userID, s.name) 31 | } 32 | -------------------------------------------------------------------------------- /room_service/service/startgame.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | ) 9 | 10 | type StartService interface { 11 | Handle(ctx context.Context) (*server.Room, error) 12 | } 13 | 14 | type startServiceImpl struct { 15 | roomID uint16 16 | userID uint32 17 | } 18 | 19 | func NewStartService(roomID uint16, userID uint32) StartService { 20 | return &startServiceImpl{ 21 | roomID: roomID, 22 | userID: userID, 23 | } 24 | } 25 | 26 | func (l *startServiceImpl) Handle(ctx context.Context) (*server.Room, error) { 27 | return client.GetRoomTableClient().StartGame(ctx, l.roomID, l.userID) 28 | } 29 | -------------------------------------------------------------------------------- /room_service/service/updateroom.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | . "github.com/KouKouChan/YuriCore/verbose" 9 | ) 10 | 11 | type UpdateRoomService interface { 12 | UpdateRoom(ctx context.Context) (*server.Room, error) 13 | UpdateRoomSafe(ctx context.Context) (*server.Room, error) 14 | } 15 | 16 | type updateRoomServiceImpl struct { 17 | room *server.Room 18 | } 19 | 20 | func NewUpdateRoomService(room *server.Room) UpdateRoomService { 21 | return &updateRoomServiceImpl{ 22 | room: room, 23 | } 24 | } 25 | 26 | func (u *updateRoomServiceImpl) UpdateRoomSafe(ctx context.Context) (*server.Room, error) { 27 | if err := client.GetRoomTableClient().UpdateRoomSafe(ctx, u.room); err != nil { 28 | return nil, err 29 | } 30 | DebugPrintf(2, "update room successfully") 31 | return client.GetRoomTableClient().GetRoomInfo(ctx, u.room.RoomId) 32 | } 33 | 34 | func (u *updateRoomServiceImpl) UpdateRoom(ctx context.Context) (*server.Room, error) { 35 | if err := client.GetRoomTableClient().UpdateRoom(ctx, u.room); err != nil { 36 | return nil, err 37 | } 38 | DebugPrintf(2, "update room successfully") 39 | return client.GetRoomTableClient().GetRoomInfo(ctx, u.room.RoomId) 40 | } 41 | -------------------------------------------------------------------------------- /room_service/start/config.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "math" 5 | 6 | "github.com/KouKouChan/YuriCore/conf" 7 | "github.com/KouKouChan/YuriCore/verbose" 8 | ) 9 | 10 | func initConfig(exePath string) { 11 | conf.Config.InitConf(exePath + "/server.conf") 12 | if conf.Config.MaxUsers <= 0 { 13 | conf.Config.MaxUsers = math.MaxUint32 14 | } 15 | verbose.Level = conf.Config.DebugLevel 16 | verbose.LogFile = conf.Config.LogFile 17 | if conf.Config.LogFile != 0 { 18 | verbose.InitLoger(exePath, "roomservice.log") 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /room_service/start/init.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | func Init(exePath string) { 4 | initConfig(exePath) 5 | initRoomTable() 6 | } 7 | -------------------------------------------------------------------------------- /room_service/start/room_table.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/server" 7 | "github.com/KouKouChan/YuriCore/room_service/client" 8 | "github.com/KouKouChan/YuriCore/room_service/infrastructure/room_table" 9 | ) 10 | 11 | func initRoomTable() { 12 | client.InitRoomTableClient(room_table.NewRoomTable()) 13 | 14 | client.GetRoomTableClient().AddServer( 15 | context.TODO(), 16 | server.Server{ 17 | ServerIndex: 0, 18 | ServerName: "普通服务器[1/2]", 19 | ServerStatus: 1, 20 | ServerType: 0, 21 | Channels: []server.Channel{}, 22 | }, 23 | ) 24 | client.GetRoomTableClient().AddChannel( 25 | context.TODO(), 26 | 1, 27 | server.Channel{ 28 | ChannelIndex: 0, 29 | ChannelName: "普通频道[1/2]", 30 | ChannelStatus: 0, 31 | ChannelType: 0, 32 | Rooms: []server.Room{}, 33 | }, 34 | ) 35 | client.GetRoomTableClient().AddChannel( 36 | context.TODO(), 37 | 1, 38 | server.Channel{ 39 | ChannelIndex: 0, 40 | ChannelName: "普通频道[2/2]", 41 | ChannelStatus: 0, 42 | ChannelType: 0, 43 | Rooms: []server.Room{}, 44 | }, 45 | ) 46 | 47 | client.GetRoomTableClient().AddServer( 48 | context.TODO(), 49 | server.Server{ 50 | ServerIndex: 0, 51 | ServerName: "普通服务器[2/2]", 52 | ServerStatus: 1, 53 | ServerType: 0, 54 | Channels: []server.Channel{}, 55 | }, 56 | ) 57 | client.GetRoomTableClient().AddChannel( 58 | context.TODO(), 59 | 2, 60 | server.Channel{ 61 | ChannelIndex: 0, 62 | ChannelName: "高手频道[1/1]", 63 | ChannelStatus: 0, 64 | ChannelType: 0, 65 | Rooms: []server.Room{}, 66 | }, 67 | ) 68 | 69 | } 70 | -------------------------------------------------------------------------------- /script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | cd `dirname $0` && pwd 2 | ./room_service & 3 | ./user_service & 4 | sleep 1 5 | ./main_service & 6 | -------------------------------------------------------------------------------- /user_service/client/db_service.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "sync" 7 | 8 | "github.com/KouKouChan/YuriCore/main_service/model/user" 9 | ) 10 | 11 | type DB interface { 12 | GetUser(ctx context.Context, username string) (*user.UserInfo, error) 13 | UpdateUser(ctx context.Context, user *user.UserInfo) error 14 | GetUserByNickName(ctx context.Context, nickname string) (*user.UserInfo, error) 15 | } 16 | 17 | var ( 18 | dbClient DB 19 | dbOnce sync.Once 20 | ) 21 | 22 | func GetDBClient() DB { 23 | return dbClient 24 | } 25 | 26 | func InitDBClient(client DB) { 27 | dbOnce.Do( 28 | func() { 29 | fmt.Println("DB service connected") 30 | dbClient = client 31 | }, 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /user_service/client/userTable.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | ) 9 | 10 | type UserTable interface { 11 | GetUserByID(ctx context.Context, id uint32) *user.UserInfo 12 | GetUserByUserName(ctx context.Context, username string) *user.UserInfo 13 | GetNewUserID(ctx context.Context) uint32 14 | UpdateUser(ctx context.Context, data *user.UserInfo) error 15 | DeleteUserByID(ctx context.Context, id uint32) error 16 | DeleteUserByName(ctx context.Context, username string) error 17 | AddUser(ctx context.Context, data *user.UserInfo) error 18 | UpdateBag(ctx context.Context, UserID uint32, BagID uint16, Slot uint8, ItemID uint16) (*user.UserInfo, error) 19 | UpdateBuymenu(ctx context.Context, UserID uint32, BuymenuID uint16, Slot uint8, ItemID uint16) (*user.UserInfo, error) 20 | UpdateCosmetics(ctx context.Context, UserID uint32, CosmeticsID uint8, cosmetics *user.UserCosmetics) (*user.UserInfo, error) 21 | UpdateCampaign(ctx context.Context, UserID uint32, CampaignID uint8) (*user.UserInfo, error) 22 | GetUserFriends(ctx context.Context, UserID uint32) ([]user.UserInfo, error) 23 | AddUserPoints(ctx context.Context, UserID uint32, num uint64) (uint64, error) 24 | AddUserCash(ctx context.Context, UserID uint32, num uint64) (uint64, error) 25 | PayPoints(ctx context.Context, UserID uint32, num uint64) (uint64, error) 26 | PayCash(ctx context.Context, UserID uint32, num uint64) (uint64, error) 27 | AddFriend(ctx context.Context, UserID uint32, friend string) (*user.UserInfo, error) 28 | UpdateOption(ctx context.Context, UserID uint32, Options []byte) (*user.UserInfo, error) 29 | UpdateNickname(ctx context.Context, UserID uint32, nickname string) (*user.UserInfo, error) 30 | } 31 | 32 | var ( 33 | userTableClient UserTable 34 | userTableOnce sync.Once 35 | ) 36 | 37 | func GetUserTableClient() UserTable { 38 | return userTableClient 39 | } 40 | 41 | func InitUserTableClient(client UserTable) { 42 | userTableOnce.Do( 43 | func() { 44 | userTableClient = client 45 | }, 46 | ) 47 | } 48 | -------------------------------------------------------------------------------- /user_service/controller/down.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/user_service/service" 8 | ) 9 | 10 | type DownController interface { 11 | Handle(ctx context.Context) error 12 | } 13 | 14 | type downControllerImpl struct { 15 | userID uint32 16 | } 17 | 18 | func NewDownController(userID uint32) DownController { 19 | return &downControllerImpl{ 20 | userID: userID, 21 | } 22 | } 23 | 24 | func (d *downControllerImpl) Handle(ctx context.Context) error { 25 | if d.userID == 0 { 26 | return errors.New("wrong user info") 27 | } 28 | 29 | return service.NewDownService(d.userID).Handle(ctx) 30 | } 31 | -------------------------------------------------------------------------------- /user_service/controller/friends.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/service" 9 | ) 10 | 11 | type FriendsController interface { 12 | Handle(ctx context.Context) ([]user.UserInfo, error) 13 | } 14 | 15 | type friendsControllerImpl struct { 16 | userID uint32 17 | } 18 | 19 | func NewFriendsController(userID uint32) FriendsController { 20 | return &friendsControllerImpl{ 21 | userID: userID, 22 | } 23 | } 24 | 25 | func (f *friendsControllerImpl) Handle(ctx context.Context) ([]user.UserInfo, error) { 26 | if f.userID == 0 { 27 | return nil, errors.New("wrong user info") 28 | } 29 | 30 | return service.NewFriendsService(f.userID).Handle(ctx) 31 | } 32 | -------------------------------------------------------------------------------- /user_service/controller/login.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/constant" 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/service" 9 | "github.com/KouKouChan/YuriCore/utils" 10 | ) 11 | 12 | type LoginController interface { 13 | Handle(ctx context.Context) (*user.UserInfo, int8) 14 | } 15 | 16 | type loginControllerImpl struct { 17 | username string 18 | password string 19 | } 20 | 21 | func NewLoginController(username, password string) LoginController { 22 | return &loginControllerImpl{ 23 | username: username, 24 | password: password, 25 | } 26 | } 27 | 28 | func (u *loginControllerImpl) Handle(ctx context.Context) (*user.UserInfo, int8) { 29 | if u.username == "" || 30 | u.username == " " || 31 | u.password == "" || 32 | !utils.PasswordFilter([]byte(u.password)) || 33 | len(u.username) > constant.MaxLen_UserName || 34 | len(u.password) > constant.MaxLen_Password { 35 | return nil, constant.Login_Wrong_Info 36 | } 37 | 38 | return service.NewLoginServiceImpl(u.username, u.password).Login(ctx) 39 | } 40 | -------------------------------------------------------------------------------- /user_service/controller/nickname.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/constant" 8 | "github.com/KouKouChan/YuriCore/main_service/model/user" 9 | "github.com/KouKouChan/YuriCore/user_service/service" 10 | ) 11 | 12 | type NickNameController interface { 13 | Handle(ctx context.Context) (*user.UserInfo, error) 14 | } 15 | 16 | type nicknameControllerImpl struct { 17 | userID uint32 18 | nickname string 19 | } 20 | 21 | func NewNickNameController(userID uint32, nickname string) NickNameController { 22 | return &nicknameControllerImpl{ 23 | userID: userID, 24 | nickname: nickname, 25 | } 26 | } 27 | 28 | func (n *nicknameControllerImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 29 | if n.nickname == "" || 30 | n.userID == 0 || 31 | len(n.nickname) > constant.MaxLen_UserName { 32 | return nil, errors.New("wrong userID or nickname") 33 | } 34 | 35 | return service.NewNickNameServiceImpl(n.userID, n.nickname).SetNickName(ctx) 36 | } 37 | -------------------------------------------------------------------------------- /user_service/controller/option.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/service" 9 | ) 10 | 11 | type UpdateOptionController interface { 12 | Handle(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type updateOptionControllerImpl struct { 16 | userID uint32 17 | data []byte 18 | } 19 | 20 | func NewUpdateOptionController(userID uint32, data []byte) UpdateOptionController { 21 | return &updateOptionControllerImpl{ 22 | userID: userID, 23 | data: data, 24 | } 25 | } 26 | 27 | func (u *updateOptionControllerImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 28 | if u.userID == 0 { 29 | return nil, errors.New("invalid userid") 30 | } 31 | return service.NewUpdateOptionServiceImpl(u.userID, u.data).Handle(ctx) 32 | } 33 | -------------------------------------------------------------------------------- /user_service/controller/register.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/constant" 8 | "github.com/KouKouChan/YuriCore/user_service/service" 9 | "github.com/KouKouChan/YuriCore/utils" 10 | ) 11 | 12 | type RegisterController interface { 13 | Handle(ctx context.Context) error 14 | } 15 | 16 | type registerControllerImpl struct { 17 | username string 18 | nickname string 19 | password string 20 | } 21 | 22 | func NewRegisterController(username, nickname, password string) RegisterController { 23 | return ®isterControllerImpl{ 24 | username: username, 25 | nickname: nickname, 26 | password: password, 27 | } 28 | } 29 | 30 | func (u *registerControllerImpl) Handle(ctx context.Context) error { 31 | if u.username == "" || 32 | u.username == " " || 33 | u.password == "" || 34 | !utils.PasswordFilter([]byte(u.password)) || 35 | len(u.nickname) > constant.MaxLen_UserName || 36 | len(u.username) > constant.MaxLen_UserName || 37 | len(u.password) > constant.MaxLen_Password { 38 | return errors.New("wrong register info") 39 | } 40 | 41 | return service.NewRegisterServiceImpl(u.username, u.nickname, u.password).Register(ctx) 42 | } 43 | -------------------------------------------------------------------------------- /user_service/controller/update.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import "context" 4 | 5 | type UpdateController interface { 6 | Handle(ctx context.Context) error 7 | } 8 | 9 | type updateControllerImpl struct { 10 | } 11 | 12 | func NewUpdateController() UpdateController { 13 | return &updateControllerImpl{} 14 | } 15 | 16 | func (u *updateControllerImpl) Handle(ctx context.Context) error { 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /user_service/controller/updatecampaign.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/service" 9 | ) 10 | 11 | type UpdateCampaignController interface { 12 | Handle(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type updateCampaignControllerImpl struct { 16 | UserID uint32 17 | campaignID uint8 18 | } 19 | 20 | func NewUpdateCampaignController(UserID uint32, campaignID uint8) UpdateCampaignController { 21 | return &updateCampaignControllerImpl{ 22 | UserID: UserID, 23 | campaignID: campaignID, 24 | } 25 | } 26 | 27 | func (u *updateCampaignControllerImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 28 | if u.UserID == 0 { 29 | return nil, errors.New("wrong userid") 30 | } 31 | 32 | return service.NewUpdateCampaignServiceImpl(u.UserID, u.campaignID).Handle(ctx) 33 | } 34 | -------------------------------------------------------------------------------- /user_service/controller/updateinventory.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/service" 9 | ) 10 | 11 | type UpdateBagController interface { 12 | Handle(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type updateBagControllerImpl struct { 16 | UserID uint32 17 | BagID uint16 18 | Slot uint8 19 | ItemID uint16 20 | } 21 | 22 | func NewUpdateBagController(UserID uint32, BagID uint16, Slot uint8, ItemID uint16) UpdateBagController { 23 | return &updateBagControllerImpl{ 24 | UserID: UserID, 25 | BagID: BagID, 26 | Slot: Slot, 27 | ItemID: ItemID, 28 | } 29 | } 30 | 31 | func (u *updateBagControllerImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 32 | if u.UserID == 0 { 33 | return nil, errors.New("wrong userid") 34 | } 35 | 36 | return service.NewUpdateBagServiceImpl(u.UserID, u.BagID, u.Slot, u.ItemID).Handle(ctx) 37 | } 38 | 39 | type UpdateBuymenuController interface { 40 | Handle(ctx context.Context) (*user.UserInfo, error) 41 | } 42 | 43 | type updateBuymenuControllerImpl struct { 44 | UserID uint32 45 | BuymenuID uint16 46 | Slot uint8 47 | ItemID uint16 48 | } 49 | 50 | func NewUpdateBuymenuController(UserID uint32, BuymenuID uint16, Slot uint8, ItemID uint16) UpdateBuymenuController { 51 | return &updateBuymenuControllerImpl{ 52 | UserID: UserID, 53 | BuymenuID: BuymenuID, 54 | Slot: Slot, 55 | ItemID: ItemID, 56 | } 57 | } 58 | 59 | func (u *updateBuymenuControllerImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 60 | if u.UserID == 0 { 61 | return nil, errors.New("wrong userid") 62 | } 63 | 64 | return service.NewUpdateBuymenuServiceImpl(u.UserID, u.BuymenuID, u.Slot, u.ItemID).Handle(ctx) 65 | } 66 | 67 | type UpdateCosmeticsController interface { 68 | Handle(ctx context.Context) (*user.UserInfo, error) 69 | } 70 | 71 | type updateCosmeticsControllerImpl struct { 72 | UserID uint32 73 | CosmeticsID uint8 74 | cosmetics *user.UserCosmetics 75 | } 76 | 77 | func NewUpdateCosmeticsController(UserID uint32, CosmeticsID uint8, cosmetics *user.UserCosmetics) UpdateCosmeticsController { 78 | return &updateCosmeticsControllerImpl{ 79 | cosmetics: cosmetics, 80 | UserID: UserID, 81 | CosmeticsID: CosmeticsID, 82 | } 83 | } 84 | 85 | func (u *updateCosmeticsControllerImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 86 | if u.UserID == 0 { 87 | return nil, errors.New("wrong userid") 88 | } 89 | 90 | return service.NewUpdateCosmeticsServiceImpl(u.UserID, u.CosmeticsID, u.cosmetics).Handle(ctx) 91 | } 92 | -------------------------------------------------------------------------------- /user_service/controller/userinfo.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/service" 9 | ) 10 | 11 | type UserInfoController interface { 12 | Handle(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type userInfoControllerImpl struct { 16 | userID uint32 17 | } 18 | 19 | func NewUserInfoController(id uint32) UserInfoController { 20 | return &userInfoControllerImpl{ 21 | userID: id, 22 | } 23 | } 24 | 25 | func (u *userInfoControllerImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 26 | if u.userID == 0 { 27 | return nil, errors.New("null userid") 28 | } 29 | 30 | return service.NewUserInfoService(u.userID).Handle(ctx) 31 | } 32 | -------------------------------------------------------------------------------- /user_service/infrastructure/db_service/db_service.go: -------------------------------------------------------------------------------- 1 | package db_service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | . "github.com/KouKouChan/YuriCore/verbose" 9 | "go.mongodb.org/mongo-driver/bson" 10 | "go.mongodb.org/mongo-driver/mongo" 11 | "go.mongodb.org/mongo-driver/mongo/options" 12 | ) 13 | 14 | type DBImpl struct { 15 | client *mongo.Client 16 | database *mongo.Database 17 | } 18 | 19 | func NewDBImpl(username, password, ip, port string) *DBImpl { 20 | url := "" 21 | if username != "" && 22 | password != "" { 23 | url = fmt.Sprintf("mongodb://%s:%s@%s:%s/", username, password, ip, port) 24 | } else { 25 | url = fmt.Sprintf("mongodb://%s:%s", ip, port) 26 | } 27 | fmt.Println("mongo uri=", url) 28 | clientOptions := options. 29 | Client(). 30 | ApplyURI(url) 31 | client, err := mongo.Connect( 32 | context.TODO(), clientOptions) 33 | if err != nil { 34 | panic(err) 35 | } 36 | if client == nil { 37 | panic("db client == null!") 38 | } 39 | 40 | database := client.Database("yuricore") 41 | if database == nil { 42 | panic("db database == null!") 43 | } 44 | 45 | return &DBImpl{ 46 | client: client, 47 | database: database, 48 | } 49 | } 50 | 51 | func (d *DBImpl) GetUser(ctx context.Context, username string) (*user.UserInfo, error) { 52 | user := &user.UserInfo{} 53 | collection := d.database.Collection("user_table") 54 | err := collection.FindOne( 55 | ctx, 56 | bson.M{ 57 | "username": username, 58 | }, 59 | ).Decode(user) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | DebugPrintf(2, "db got user %+v", *user) 65 | return user, nil 66 | } 67 | 68 | func (d *DBImpl) GetUserByNickName(ctx context.Context, nickname string) (*user.UserInfo, error) { 69 | user := &user.UserInfo{} 70 | collection := d.database.Collection("user_table") 71 | err := collection.FindOne( 72 | ctx, 73 | bson.M{ 74 | "nickname": nickname, 75 | }, 76 | ).Decode(user) 77 | if err != nil { 78 | return nil, err 79 | } 80 | 81 | DebugPrintf(2, "db got user %+v", *user) 82 | return user, nil 83 | } 84 | 85 | func (d *DBImpl) UpdateUser(ctx context.Context, user *user.UserInfo) error { 86 | collection := d.database.Collection("user_table") 87 | filter := bson.M{"username": user.UserName} 88 | update := bson.M{ 89 | "$set": user, 90 | } 91 | options := new(options.UpdateOptions) 92 | options.SetUpsert(true) 93 | _, err := collection.UpdateOne( 94 | ctx, 95 | filter, 96 | update, 97 | options, 98 | ) 99 | DebugPrintf(2, "db update user %+v", *user) 100 | return err 101 | } 102 | -------------------------------------------------------------------------------- /user_service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/KouKouChan/YuriCore/conf" 7 | "github.com/KouKouChan/YuriCore/user_service/start" 8 | "github.com/KouKouChan/YuriCore/utils" 9 | ) 10 | 11 | func main() { 12 | ExePath, err := utils.GetExePath() 13 | if err != nil { 14 | panic(err) 15 | } 16 | 17 | start.Init(ExePath) 18 | initServer(ExePath, fmt.Sprintf("%s:%d", conf.Config.UserAdress, conf.Config.UserPort)) 19 | } 20 | -------------------------------------------------------------------------------- /user_service/service/down.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/user_service/client" 8 | . "github.com/KouKouChan/YuriCore/verbose" 9 | ) 10 | 11 | type DownService interface { 12 | Handle(ctx context.Context) error 13 | } 14 | 15 | type downServiceImpl struct { 16 | userID uint32 17 | } 18 | 19 | func NewDownService(userID uint32) DownService { 20 | return &downServiceImpl{ 21 | userID: userID, 22 | } 23 | } 24 | 25 | func (d *downServiceImpl) Handle(ctx context.Context) error { 26 | u := client.GetUserTableClient().GetUserByID(ctx, d.userID) 27 | if u == nil || u.UserID == 0 { 28 | return errors.New("down: wrong user id") 29 | } 30 | if err := client.GetDBClient().UpdateUser(ctx, u); err != nil { 31 | DebugPrintf(2, "down: update user failed! user=%+v\n", *u) 32 | } 33 | return client.GetUserTableClient().DeleteUserByID(ctx, d.userID) 34 | } 35 | -------------------------------------------------------------------------------- /user_service/service/friends.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/user" 7 | "github.com/KouKouChan/YuriCore/user_service/client" 8 | ) 9 | 10 | type FriendsService interface { 11 | Handle(ctx context.Context) ([]user.UserInfo, error) 12 | } 13 | 14 | type friendsServiceImpl struct { 15 | userID uint32 16 | } 17 | 18 | func NewFriendsService(userID uint32) FriendsService { 19 | return &friendsServiceImpl{ 20 | userID: userID, 21 | } 22 | } 23 | 24 | func (f *friendsServiceImpl) Handle(ctx context.Context) ([]user.UserInfo, error) { 25 | 26 | return client.GetUserTableClient().GetUserFriends(ctx, f.userID) 27 | } 28 | -------------------------------------------------------------------------------- /user_service/service/login.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "crypto/md5" 6 | "fmt" 7 | "sync" 8 | 9 | "github.com/KouKouChan/YuriCore/conf" 10 | "github.com/KouKouChan/YuriCore/main_service/constant" 11 | "github.com/KouKouChan/YuriCore/main_service/model/user" 12 | "github.com/KouKouChan/YuriCore/user_service/client" 13 | ) 14 | 15 | type LoginService interface { 16 | Login(ctx context.Context) (*user.UserInfo, int8) 17 | } 18 | 19 | type loginServiceImpl struct { 20 | username string 21 | password string 22 | loginLock sync.Mutex 23 | } 24 | 25 | func NewLoginServiceImpl(username, password string) *loginServiceImpl { 26 | return &loginServiceImpl{ 27 | username: username, 28 | password: password, 29 | loginLock: sync.Mutex{}, 30 | } 31 | } 32 | 33 | func (l *loginServiceImpl) Login(ctx context.Context) (*user.UserInfo, int8) { 34 | l.loginLock.Lock() 35 | defer l.loginLock.Unlock() 36 | var user *user.UserInfo 37 | if conf.Config.EnableDataBase != 1 { 38 | // 创建用户 39 | user = NewRegisterServiceImpl(l.username, l.username, l.password).newUser_Default() 40 | } else { 41 | // 读取用户数据 42 | db_user, err := client.GetDBClient().GetUser(ctx, l.username) 43 | if err != nil { 44 | return nil, constant.Login_DB_ERROR 45 | } 46 | if db_user == nil || db_user.UserName == "" || db_user.Password == "" { 47 | return nil, constant.Login_Not_Registed 48 | } 49 | // 校验用户数据 50 | if !checkPassword(l.username, l.password, db_user.Password) { 51 | return nil, constant.Login_Wrong_PASSWORD 52 | } 53 | user = db_user 54 | } 55 | 56 | // 是否已经登录 57 | check_u := client.GetUserTableClient().GetUserByUserName(ctx, user.UserName) 58 | if check_u != nil && check_u.UserID != 0 { 59 | return nil, constant.Login_Already 60 | } 61 | // 获取用户ID 62 | user.UserID = client.GetUserTableClient().GetNewUserID(ctx) 63 | user.ChatTimes = 0xff 64 | // TODO fixme 65 | user.UserInventory.Items = full_inventory.Items 66 | // 存入table 67 | client.GetUserTableClient().AddUser(ctx, user) 68 | return user, constant.Login_Success 69 | } 70 | 71 | func checkPassword(username, password, DBpassword string) bool { 72 | str := fmt.Sprintf("%x", md5.Sum([]byte(username+password))) 73 | for i := 0; i < 32; i++ { 74 | if str[i] != DBpassword[i] { 75 | return false 76 | } 77 | } 78 | return true 79 | } 80 | -------------------------------------------------------------------------------- /user_service/service/nickname.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/client" 9 | ) 10 | 11 | type NickNameService interface { 12 | SetNickName(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type nicknameServiceImpl struct { 16 | userID uint32 17 | nickname string 18 | } 19 | 20 | func NewNickNameServiceImpl(userID uint32, nickname string) *nicknameServiceImpl { 21 | return &nicknameServiceImpl{ 22 | userID: userID, 23 | nickname: nickname, 24 | } 25 | } 26 | 27 | func (n *nicknameServiceImpl) SetNickName(ctx context.Context) (*user.UserInfo, error) { 28 | // 检查是否重复 29 | db_user, err := client.GetDBClient().GetUserByNickName(ctx, n.nickname) 30 | if err != nil && 31 | err.Error() != "mongo: no documents in result" { 32 | return nil, err 33 | } 34 | if db_user != nil { 35 | return nil, errors.New("nickname existed!") 36 | } 37 | 38 | return client.GetUserTableClient().UpdateNickname(ctx, n.userID, n.nickname) 39 | } 40 | -------------------------------------------------------------------------------- /user_service/service/option.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/user" 7 | "github.com/KouKouChan/YuriCore/user_service/client" 8 | ) 9 | 10 | type UpdateOptionService interface { 11 | Handle(ctx context.Context) (*user.UserInfo, error) 12 | } 13 | 14 | type updateOptionServiceImpl struct { 15 | UserID uint32 16 | data []byte 17 | } 18 | 19 | func NewUpdateOptionServiceImpl(UserID uint32, data []byte) UpdateOptionService { 20 | return &updateOptionServiceImpl{ 21 | UserID: UserID, 22 | data: data, 23 | } 24 | } 25 | 26 | func (u *updateOptionServiceImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 27 | 28 | return client.GetUserTableClient().UpdateOption(ctx, u.UserID, u.data) 29 | } 30 | -------------------------------------------------------------------------------- /user_service/service/update.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type UpdateService interface { 8 | Update(ctx context.Context) error 9 | } 10 | 11 | type updateServiceImpl struct { 12 | } 13 | 14 | func NewUpdateServiceImpl() *updateServiceImpl { 15 | return &updateServiceImpl{} 16 | } 17 | 18 | func (u *updateServiceImpl) Update(ctx context.Context) error { 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /user_service/service/updateCosmetics.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/client" 9 | ) 10 | 11 | type UpdateCosmeticsService interface { 12 | Handle(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type updateCosmeticsServiceImpl struct { 16 | UserID uint32 17 | CosmeticsID uint8 18 | cosmetics *user.UserCosmetics 19 | } 20 | 21 | func NewUpdateCosmeticsServiceImpl(UserID uint32, CosmeticsID uint8, cosmetics *user.UserCosmetics) UpdateCosmeticsService { 22 | return &updateCosmeticsServiceImpl{ 23 | cosmetics: cosmetics, 24 | UserID: UserID, 25 | CosmeticsID: CosmeticsID, 26 | } 27 | } 28 | 29 | func (u *updateCosmeticsServiceImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 30 | if u.UserID == 0 { 31 | return nil, errors.New("invalid userid") 32 | } 33 | 34 | return client.GetUserTableClient().UpdateCosmetics(ctx, u.UserID, u.CosmeticsID, u.cosmetics) 35 | } 36 | -------------------------------------------------------------------------------- /user_service/service/updatebag.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/user" 7 | "github.com/KouKouChan/YuriCore/user_service/client" 8 | ) 9 | 10 | type UpdateBagService interface { 11 | Handle(ctx context.Context) (*user.UserInfo, error) 12 | } 13 | 14 | type updateBagServiceImpl struct { 15 | UserID uint32 16 | BagID uint16 17 | Slot uint8 18 | ItemID uint16 19 | } 20 | 21 | func NewUpdateBagServiceImpl(UserID uint32, BagID uint16, Slot uint8, ItemID uint16) UpdateBagService { 22 | return &updateBagServiceImpl{ 23 | UserID: UserID, 24 | BagID: BagID, 25 | Slot: Slot, 26 | ItemID: ItemID, 27 | } 28 | } 29 | 30 | func (u *updateBagServiceImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 31 | 32 | return client.GetUserTableClient().UpdateBag(ctx, u.UserID, u.BagID, u.Slot, u.ItemID) 33 | } 34 | -------------------------------------------------------------------------------- /user_service/service/updatebuymenu.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/KouKouChan/YuriCore/main_service/model/user" 7 | "github.com/KouKouChan/YuriCore/user_service/client" 8 | ) 9 | 10 | type UpdateBuymenuService interface { 11 | Handle(ctx context.Context) (*user.UserInfo, error) 12 | } 13 | 14 | type updateBuymenuServiceImpl struct { 15 | UserID uint32 16 | BuymenuID uint16 17 | Slot uint8 18 | ItemID uint16 19 | } 20 | 21 | func NewUpdateBuymenuServiceImpl(UserID uint32, BuymenuID uint16, Slot uint8, ItemID uint16) UpdateBuymenuService { 22 | return &updateBuymenuServiceImpl{ 23 | UserID: UserID, 24 | BuymenuID: BuymenuID, 25 | Slot: Slot, 26 | ItemID: ItemID, 27 | } 28 | } 29 | 30 | func (u *updateBuymenuServiceImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 31 | 32 | return client.GetUserTableClient().UpdateBuymenu(ctx, u.UserID, u.BuymenuID, u.Slot, u.ItemID) 33 | } 34 | -------------------------------------------------------------------------------- /user_service/service/updatecampaign.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/client" 9 | ) 10 | 11 | type UpdateCampaignService interface { 12 | Handle(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type updateCampaignServiceImpl struct { 16 | UserID uint32 17 | CampaignID uint8 18 | } 19 | 20 | func NewUpdateCampaignServiceImpl(UserID uint32, CampaignID uint8) UpdateCampaignService { 21 | return &updateCampaignServiceImpl{ 22 | UserID: UserID, 23 | CampaignID: CampaignID, 24 | } 25 | } 26 | 27 | func (u *updateCampaignServiceImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 28 | if u.UserID == 0 { 29 | return nil, errors.New("invalid userid") 30 | } 31 | 32 | return client.GetUserTableClient().UpdateCampaign(ctx, u.UserID, u.CampaignID) 33 | } 34 | -------------------------------------------------------------------------------- /user_service/service/userinfo.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/KouKouChan/YuriCore/main_service/model/user" 8 | "github.com/KouKouChan/YuriCore/user_service/client" 9 | ) 10 | 11 | type UserInfoService interface { 12 | Handle(ctx context.Context) (*user.UserInfo, error) 13 | } 14 | 15 | type userInfoServiceImpl struct { 16 | userID uint32 17 | } 18 | 19 | func NewUserInfoService(id uint32) UserInfoService { 20 | return &userInfoServiceImpl{ 21 | userID: id, 22 | } 23 | } 24 | 25 | func (u *userInfoServiceImpl) Handle(ctx context.Context) (*user.UserInfo, error) { 26 | info := client.GetUserTableClient().GetUserByID(ctx, u.userID) 27 | 28 | if info == nil { 29 | return nil, errors.New("can't get user") 30 | } 31 | 32 | return client.GetUserTableClient().GetUserByID(ctx, u.userID), nil 33 | } 34 | -------------------------------------------------------------------------------- /user_service/start/config.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "math" 5 | 6 | "github.com/KouKouChan/YuriCore/conf" 7 | "github.com/KouKouChan/YuriCore/verbose" 8 | ) 9 | 10 | func initConfig(exePath string) { 11 | conf.Config.InitConf(exePath + "/server.conf") 12 | if conf.Config.MaxUsers <= 0 { 13 | conf.Config.MaxUsers = math.MaxUint32 14 | } 15 | verbose.Level = conf.Config.DebugLevel 16 | verbose.LogFile = conf.Config.LogFile 17 | if conf.Config.LogFile != 0 { 18 | verbose.InitLoger(exePath, "userservice.log") 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /user_service/start/db_service.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/conf" 5 | "github.com/KouKouChan/YuriCore/user_service/client" 6 | "github.com/KouKouChan/YuriCore/user_service/infrastructure/db_service" 7 | ) 8 | 9 | func InitDBService() { 10 | client.InitDBClient(db_service.NewDBImpl( 11 | conf.Config.DBUserName, 12 | conf.Config.DBpassword, 13 | conf.Config.DBaddress, 14 | conf.Config.DBport, 15 | )) 16 | } 17 | -------------------------------------------------------------------------------- /user_service/start/init.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import "github.com/KouKouChan/YuriCore/conf" 4 | 5 | func Init(exePath string) { 6 | initConfig(exePath) 7 | if conf.Config.EnableDataBase == 1 { 8 | InitDBService() 9 | } 10 | initUserTable() 11 | } 12 | -------------------------------------------------------------------------------- /user_service/start/user_table.go: -------------------------------------------------------------------------------- 1 | package start 2 | 3 | import ( 4 | "github.com/KouKouChan/YuriCore/user_service/client" 5 | "github.com/KouKouChan/YuriCore/user_service/infrastructure/userTable" 6 | ) 7 | 8 | func initUserTable() { 9 | client.InitUserTableClient(userTable.NewUserTableImpl()) 10 | } 11 | -------------------------------------------------------------------------------- /utils/bloomfilter.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/willf/bitset" 5 | ) 6 | 7 | type SimpleHash struct { 8 | cap uint 9 | seed uint 10 | } 11 | 12 | type BloomFilter struct { 13 | Size uint 14 | Set *bitset.BitSet 15 | Funcs []SimpleHash 16 | } 17 | 18 | func (s SimpleHash) Hash(value string) uint { 19 | var result uint = 0 20 | for i := 0; i < len(value); i++ { 21 | result = result*s.seed + uint(value[i]) 22 | } 23 | return (s.cap - 1) & result 24 | } 25 | 26 | //Contains 是否可能存在 27 | func (bf BloomFilter) Contains(value string) bool { 28 | if value == "" { 29 | return false 30 | } 31 | ret := true 32 | for _, f := range bf.Funcs { 33 | ret = ret && bf.Set.Test(f.Hash(value)) 34 | } 35 | return ret 36 | } 37 | 38 | //NewBloomFilter 新建一个bloomfilter 39 | func NewBloomFilter(size uint, seeds []uint) *BloomFilter { 40 | bf := new(BloomFilter) 41 | if size < uint(len(seeds)) { 42 | bf.Size = 2 << 24 43 | 44 | } else { 45 | bf.Size = size 46 | } 47 | bf.Funcs = make([]SimpleHash, len(seeds)) 48 | for i := 0; i < len(bf.Funcs); i++ { 49 | bf.Funcs[i] = SimpleHash{bf.Size, seeds[i]} 50 | } 51 | bf.Set = bitset.New(bf.Size) 52 | return bf 53 | } 54 | 55 | //Add 添加一个数据 56 | func (bf BloomFilter) Add(value string) { 57 | for _, f := range bf.Funcs { 58 | bf.Set.Set(f.Hash(value)) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /utils/encode.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | iconv "github.com/djimenez/iconv-go" 5 | ) 6 | 7 | var ( 8 | CVtolocal *iconv.Converter 9 | CVtoutf8 *iconv.Converter 10 | ) 11 | 12 | func InitConverter(local string) bool { 13 | cv, err := iconv.NewConverter("utf-8", local) 14 | if err != nil { 15 | panic(err) 16 | } 17 | CVtolocal = cv 18 | cv, err = iconv.NewConverter(local, "utf-8") 19 | if err != nil { 20 | panic(err) 21 | } 22 | CVtoutf8 = cv 23 | return true 24 | } 25 | 26 | func Utf8ToLocal(str string) (b string, err error) { 27 | buf, err := CVtolocal.ConvertString(str) 28 | return string(buf), err 29 | } 30 | 31 | func LocalToUtf8(str string) (b string, err error) { 32 | buf, err := CVtoutf8.ConvertString(str) 33 | return string(buf), err 34 | } 35 | -------------------------------------------------------------------------------- /utils/error.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "fmt" 4 | 5 | //CheckErr 有错误就显示 6 | func CheckErr(err error) { 7 | if err != nil { 8 | fmt.Println(err) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /utils/ini.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "gopkg.in/ini.v1" 5 | ) 6 | 7 | type ( 8 | IniParser struct { 9 | conf_reader *ini.File // config reader 10 | } 11 | 12 | IniParserError struct { 13 | error_info string 14 | } 15 | ) 16 | 17 | func (e *IniParserError) Error() string { return e.error_info } 18 | 19 | func (this *IniParser) LoadIni(config_file_name string) error { 20 | conf, err := ini.Load(config_file_name) 21 | if err != nil { 22 | this.conf_reader = nil 23 | return err 24 | } 25 | this.conf_reader = conf 26 | return nil 27 | } 28 | 29 | func (this *IniParser) IniGetString(section string, key string) string { 30 | if this.conf_reader == nil { 31 | return "" 32 | } 33 | 34 | s := this.conf_reader.Section(section) 35 | if s == nil { 36 | return "" 37 | } 38 | 39 | return s.Key(key).String() 40 | } 41 | 42 | func (this *IniParser) IniGetInt32(section string, key string) int32 { 43 | if this.conf_reader == nil { 44 | return 0 45 | } 46 | 47 | s := this.conf_reader.Section(section) 48 | if s == nil { 49 | return 0 50 | } 51 | 52 | value_int, _ := s.Key(key).Int() 53 | 54 | return int32(value_int) 55 | } 56 | 57 | func (this *IniParser) IniGetUint32(section string, key string) uint32 { 58 | if this.conf_reader == nil { 59 | return 0 60 | } 61 | 62 | s := this.conf_reader.Section(section) 63 | if s == nil { 64 | return 0 65 | } 66 | 67 | value_int, _ := s.Key(key).Uint() 68 | 69 | return uint32(value_int) 70 | } 71 | 72 | func (this *IniParser) IniGetInt64(section string, key string) int64 { 73 | if this.conf_reader == nil { 74 | return 0 75 | } 76 | 77 | s := this.conf_reader.Section(section) 78 | if s == nil { 79 | return 0 80 | } 81 | 82 | value_int, _ := s.Key(key).Int64() 83 | return value_int 84 | } 85 | 86 | func (this *IniParser) IniGetUint64(section string, key string) uint64 { 87 | if this.conf_reader == nil { 88 | return 0 89 | } 90 | 91 | s := this.conf_reader.Section(section) 92 | if s == nil { 93 | return 0 94 | } 95 | 96 | value_int, _ := s.Key(key).Uint64() 97 | return value_int 98 | } 99 | 100 | func (this *IniParser) IniGetFloat32(section string, key string) float32 { 101 | if this.conf_reader == nil { 102 | return 0 103 | } 104 | 105 | s := this.conf_reader.Section(section) 106 | if s == nil { 107 | return 0 108 | } 109 | 110 | value_float, _ := s.Key(key).Float64() 111 | return float32(value_float) 112 | } 113 | 114 | func (this *IniParser) IniGetFloat64(section string, key string) float64 { 115 | if this.conf_reader == nil { 116 | return 0 117 | } 118 | 119 | s := this.conf_reader.Section(section) 120 | if s == nil { 121 | return 0 122 | } 123 | 124 | value_float, _ := s.Key(key).Float64() 125 | return value_float 126 | } 127 | -------------------------------------------------------------------------------- /utils/int.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | func ConvertUint32sToInt32s(src []uint32) []int32 { 4 | int32s := make([]int32, len(src)) 5 | for i := range src { 6 | int32s[i] = int32(src[i]) 7 | } 8 | return int32s 9 | } 10 | 11 | func Convertint32sToUint32s(src []int32) []uint32 { 12 | uint32s := make([]uint32, len(src)) 13 | for i := range src { 14 | uint32s[i] = uint32(src[i]) 15 | } 16 | return uint32s 17 | } 18 | 19 | func ConvertUint16sToInt16s(src []uint16) []int16 { 20 | int16s := make([]int16, len(src)) 21 | for i := range src { 22 | int16s[i] = int16(src[i]) 23 | } 24 | return int16s 25 | } 26 | 27 | func Convertint16sToUint16s(src []int16) []uint16 { 28 | uint16s := make([]uint16, len(src)) 29 | for i := range src { 30 | uint16s[i] = uint16(src[i]) 31 | } 32 | return uint16s 33 | } 34 | 35 | func Convert9Uint16sToInt16s(src [9]uint16) []int16 { 36 | int16s := make([]int16, 9) 37 | for i := range src { 38 | int16s[i] = int16(src[i]) 39 | } 40 | return int16s 41 | } 42 | 43 | func Convertint16sTo9Uint16s(src []int16) [9]uint16 { 44 | uint16s := [9]uint16{} 45 | for i := range src { 46 | uint16s[i] = uint16(src[i]) 47 | } 48 | return uint16s 49 | } 50 | -------------------------------------------------------------------------------- /utils/ip.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net" 7 | ) 8 | 9 | //IPToUint32 把IP转换成4字节uint 10 | func IPToUint32(s string) (uint32, error) { 11 | var ip uint32 12 | ipobj := net.ParseIP(s) 13 | if ipobj == nil { 14 | return ip, errors.New("Prase IP error !") 15 | } else { 16 | ip |= uint32(ipobj[12]) << 24 17 | ip |= uint32(ipobj[13]) << 16 18 | ip |= uint32(ipobj[14]) << 8 19 | ip |= uint32(ipobj[15]) 20 | } 21 | return ip, nil 22 | } 23 | 24 | //SlideIP 切割IP,找到:位置 25 | func SlideIP(s string) int { 26 | for k, v := range s { 27 | if v == ':' { 28 | return k 29 | } 30 | } 31 | return 0 32 | } 33 | 34 | //GetIP 获取IP 35 | func GetIP() string { 36 | netInterfaces, err := net.Interfaces() 37 | if err != nil { 38 | fmt.Println("net.Interfaces failed, err:", err.Error()) 39 | } 40 | 41 | for i := 0; i < len(netInterfaces); i++ { 42 | if (netInterfaces[i].Flags & net.FlagUp) != 0 { 43 | addrs, _ := netInterfaces[i].Addrs() 44 | for _, address := range addrs { 45 | if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { 46 | if ipnet.IP.To4() != nil { 47 | return ipnet.IP.String() 48 | } 49 | } 50 | } 51 | } 52 | } 53 | return "Error" 54 | } 55 | 56 | //IsSameLan 判断两个IP是否处于同一局域网 57 | func IsSameLan(a []byte, b []byte) bool { 58 | idx, i := 0, 0 59 | for { 60 | if len(a) <= i || len(b) <= i { 61 | return false 62 | } 63 | if a[i] == b[i] { 64 | if a[i] == '.' { 65 | idx++ 66 | if idx == 3 { 67 | return true 68 | } 69 | } 70 | } else { 71 | return false 72 | } 73 | i++ 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /utils/kerlong.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "fmt" 4 | 5 | //IntAbs 绝对值 6 | func IntAbs(num int) int { 7 | ans, ok := Ternary(num > 0, num, -num).(int) 8 | if ok { 9 | return ans 10 | } 11 | return 0 12 | } 13 | 14 | //Ternary 三目运算符 15 | func Ternary(b bool, t, f interface{}) interface{} { 16 | if b { 17 | return t 18 | } 19 | return f 20 | } 21 | 22 | func IsAllNumber(str string) bool { 23 | for i := 0; i < len(str); i++ { 24 | if str[i] > '9' || str[i] < '0' { 25 | return false 26 | } 27 | } 28 | return true 29 | } 30 | 31 | //ScanLine 得到一行 32 | func ScanLine() (line string) { 33 | var buffer []rune 34 | for { 35 | var c rune 36 | n, err := fmt.Scanf("%c", &c) 37 | 38 | //FIXME: in windows,line feeds are '\r\n',but this may cause some problem in UNIX or MAXOS 39 | if nil != err || 40 | 1 != n || 41 | //'\r' == c || 42 | '\n' == c { 43 | break 44 | } 45 | buffer = append(buffer, c) 46 | } 47 | return string(buffer) 48 | } 49 | -------------------------------------------------------------------------------- /utils/mail.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "gopkg.in/gomail.v2" 5 | ) 6 | 7 | type EmailData struct { 8 | SenderMail string 9 | SenderCode string 10 | SenderSMTP string 11 | TargetMail string 12 | MailSubHeader string 13 | MailHeader string 14 | Content string 15 | } 16 | 17 | func SendEmailTO(mail *EmailData) error { 18 | m := gomail.NewMessage() 19 | m.SetAddressHeader("From", mail.SenderMail, mail.MailSubHeader) // 发件人 20 | m.SetHeader("To", // 收件人 21 | m.FormatAddress(mail.TargetMail, "111"), 22 | ) 23 | m.SetHeader("Subject", mail.MailHeader) // 主题 24 | body := mail.Content 25 | m.SetBody("text/html", body) // 正文 26 | 27 | d := gomail.NewPlainDialer(mail.SenderSMTP, 465, mail.SenderMail, mail.SenderCode) // 发送邮件服务器、端口、发件人账号、发件人密码 28 | 29 | err := d.DialAndSend(m) 30 | 31 | return err 32 | } 33 | -------------------------------------------------------------------------------- /utils/password.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | func PasswordFilter(str []byte) bool { 4 | rst := true 5 | for i := range str { 6 | if str[i] >= '0' && str[i] <= '9' || 7 | str[i] >= 'a' && str[i] <= 'z' || 8 | str[i] >= 'A' && str[i] <= 'Z' || 9 | str[i] == '_' || 10 | str[i] == 0x00 { 11 | } else { 12 | rst = false 13 | break 14 | } 15 | } 16 | return rst 17 | } 18 | -------------------------------------------------------------------------------- /utils/path.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | ) 7 | 8 | //GetExePath() 获取当前可执行文件所在目录 9 | func GetExePath() (string, error) { 10 | ePath, err := os.Executable() 11 | if err != nil { 12 | return "", err 13 | } 14 | return filepath.Dir(ePath), nil 15 | } 16 | -------------------------------------------------------------------------------- /utils/radom.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "math/rand" 5 | ) 6 | 7 | //RandInt64 随机一个int64数字 8 | func RandInt64(min, max int64) int64 { 9 | if min >= max { 10 | return max 11 | } 12 | return rand.Int63n(max-min) + min 13 | } 14 | 15 | //RandInt32 随机一个int32数字 16 | func RandInt32(min, max int32) int32 { 17 | if min >= max { 18 | return max 19 | } 20 | return rand.Int31n(max-min) + min 21 | } 22 | 23 | //RandInt16 随机一个int32数字 24 | func RandInt16(min, max int16) int16 { 25 | if min >= max { 26 | return max 27 | } 28 | return int16(rand.Int31n(int32(max-min)) + int32(min)) 29 | } 30 | -------------------------------------------------------------------------------- /verbose/loger.go: -------------------------------------------------------------------------------- 1 | package verbose 2 | 3 | import ( 4 | "log" 5 | "os" 6 | ) 7 | 8 | var Loger *log.Logger 9 | 10 | func InitLoger(path, name string) { 11 | file := path + "/" + name 12 | logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE, 0766) 13 | if err != nil { 14 | panic(err) 15 | } 16 | Loger = log.New(logFile, "", log.LstdFlags|log.LUTC) // 将文件设置为loger作为输出 17 | } 18 | -------------------------------------------------------------------------------- /verbose/verbose.go: -------------------------------------------------------------------------------- 1 | package verbose 2 | 3 | import ( 4 | "log" 5 | ) 6 | 7 | var ( 8 | Level uint32 9 | LogFile uint32 10 | IsConsole uint32 11 | ) 12 | 13 | func DebugInfo(l uint32, v ...interface{}) { 14 | if l <= Level { 15 | log.Println(v...) 16 | if LogFile != 0 { 17 | Loger.Println(v...) 18 | } 19 | } 20 | } 21 | 22 | func DebugPrintf(l uint32, format string, v ...interface{}) { 23 | if l <= Level { 24 | log.Printf(format, v...) 25 | if LogFile != 0 { 26 | Loger.Printf(format, v...) 27 | } 28 | } 29 | } 30 | --------------------------------------------------------------------------------