├── .gitignore ├── LICENSE ├── build.sh ├── common ├── conf │ └── sensitive.txt ├── define │ └── const.go ├── gamedata │ ├── data │ │ ├── DropItemConfing.conf │ │ ├── GlobalConfig.conf │ │ ├── ItemConfig.conf │ │ ├── MachineConfig.conf │ │ ├── MallConfig.conf │ │ ├── RechargeConfig.conf │ │ ├── TaskConfig.conf │ │ ├── TexasConfig.conf │ │ ├── TexasTestConfig.conf │ │ └── gamedata.tar │ ├── gamedata.go │ ├── gamedata_test.go │ └── repository │ │ ├── drop_item_confing │ │ └── DropItemConfingData.gen.go │ │ ├── global_config │ │ └── GlobalData.gen.go │ │ ├── item_config │ │ └── ItemData.gen.go │ │ ├── machine_config │ │ └── MachineData.gen.go │ │ ├── mall_config │ │ └── MallData.gen.go │ │ ├── recharge_config │ │ └── RechargeData.gen.go │ │ ├── task_config │ │ └── TaskData.gen.go │ │ ├── texas_config │ │ └── TexasData.gen.go │ │ └── texas_test_config │ │ └── TexasTestData.gen.go ├── gconf │ ├── config.go │ ├── config_test.go │ ├── server_conf.yaml │ └── server_conf_ide.yaml └── gfunc │ ├── game_func.go │ ├── notify.go │ └── pub_func.go ├── deploy ├── deploy.sh ├── hosts │ └── host_dev.txt ├── inithost │ ├── host.txt │ ├── init_centos_bak.yaml │ └── inithost.yml ├── playbook_dev │ ├── dev1.yml │ ├── dev1_vars │ ├── dev2.yml │ ├── dev2_vars │ ├── dev_local.yml │ └── dev_local_vars ├── roles │ ├── chatsvr │ │ └── tasks │ │ │ └── main.yml │ ├── commconf │ │ ├── tasks │ │ │ └── main.yml │ │ └── templates │ │ │ └── server_conf.yaml │ ├── connsvr │ │ └── tasks │ │ │ └── main.yml │ ├── friendsvr │ │ └── tasks │ │ │ └── main.yml │ ├── gamedata │ │ └── tasks │ │ │ └── main.yml │ ├── infosvr │ │ └── tasks │ │ │ └── main.yml │ ├── mailsvr │ │ └── tasks │ │ │ └── main.yml │ ├── mainsvr │ │ └── tasks │ │ │ └── main.yml │ ├── mysqlsvr │ │ └── tasks │ │ │ └── main.yml │ ├── roomcentersvr │ │ └── tasks │ │ │ └── main.yml │ └── texassvr │ │ └── tasks │ │ └── main.yml └── scripts │ └── server.sh ├── doc ├── G1服务器技术架构文档.docx ├── setup_linux.md └── setup_win.md ├── env ├── docker.yaml └── server_conf_ide.yaml ├── go.mod ├── go.sum ├── lib ├── api │ ├── cmd_handler │ │ └── cmd_handler_i.go │ ├── datetime │ │ ├── const.go │ │ ├── datetime.go │ │ └── zonetime.go │ ├── error_capture │ │ ├── bugsnag.go │ │ ├── error_capture_test.go │ │ └── sentry.go │ ├── http_sign │ │ ├── Sign.go │ │ ├── Sign_Mgr.go │ │ ├── Transform.go │ │ └── config.go │ ├── logger │ │ ├── logger.go │ │ ├── plug │ │ │ ├── cmd_blacklist.go │ │ │ └── notify.go │ │ └── zap │ │ │ ├── logger.go │ │ │ ├── logger_test.go │ │ │ └── logging.go │ ├── net_conf │ │ └── nacos_config.go │ ├── rest_api │ │ ├── config.go │ │ ├── rest_api.go │ │ └── rest_api_mgr.go │ ├── sharedstruct │ │ ├── cs_packet.go │ │ ├── packet_test.go │ │ └── ss_packet.go │ └── uerror │ │ └── uerror.go ├── contrib │ ├── config │ │ ├── apollo │ │ │ ├── README.md │ │ │ ├── apollo.go │ │ │ ├── apollo_test.go │ │ │ ├── json_parser.go │ │ │ └── watcher.go │ │ ├── consul │ │ │ ├── README.md │ │ │ ├── config.go │ │ │ ├── config_test.go │ │ │ └── watcher.go │ │ ├── etcd │ │ │ ├── README.md │ │ │ ├── config.go │ │ │ ├── config_test.go │ │ │ └── watcher.go │ │ └── kubernetes │ │ │ ├── README.md │ │ │ ├── config.go │ │ │ ├── config_test.go │ │ │ ├── watcher.go │ │ │ └── watcher_test.go │ ├── protoc │ │ ├── protoc-30.1-linux-x86_64 │ │ │ ├── bin │ │ │ │ └── protoc │ │ │ ├── include │ │ │ │ └── google │ │ │ │ │ └── protobuf │ │ │ │ │ ├── any.proto │ │ │ │ │ ├── api.proto │ │ │ │ │ ├── compiler │ │ │ │ │ └── plugin.proto │ │ │ │ │ ├── cpp_features.proto │ │ │ │ │ ├── descriptor.proto │ │ │ │ │ ├── duration.proto │ │ │ │ │ ├── empty.proto │ │ │ │ │ ├── field_mask.proto │ │ │ │ │ ├── go_features.proto │ │ │ │ │ ├── java_features.proto │ │ │ │ │ ├── source_context.proto │ │ │ │ │ ├── struct.proto │ │ │ │ │ ├── timestamp.proto │ │ │ │ │ ├── type.proto │ │ │ │ │ └── wrappers.proto │ │ │ └── readme.txt │ │ ├── protoc-30.1-osx-aarch_64 │ │ │ ├── bin │ │ │ │ └── protoc │ │ │ ├── include │ │ │ │ └── google │ │ │ │ │ └── protobuf │ │ │ │ │ ├── any.proto │ │ │ │ │ ├── api.proto │ │ │ │ │ ├── compiler │ │ │ │ │ └── plugin.proto │ │ │ │ │ ├── cpp_features.proto │ │ │ │ │ ├── descriptor.proto │ │ │ │ │ ├── duration.proto │ │ │ │ │ ├── empty.proto │ │ │ │ │ ├── field_mask.proto │ │ │ │ │ ├── go_features.proto │ │ │ │ │ ├── java_features.proto │ │ │ │ │ ├── source_context.proto │ │ │ │ │ ├── struct.proto │ │ │ │ │ ├── timestamp.proto │ │ │ │ │ ├── type.proto │ │ │ │ │ └── wrappers.proto │ │ │ └── readme.txt │ │ └── protoc-30.1-win64 │ │ │ ├── include │ │ │ └── google │ │ │ │ └── protobuf │ │ │ │ ├── any.proto │ │ │ │ ├── api.proto │ │ │ │ ├── compiler │ │ │ │ └── plugin.proto │ │ │ │ ├── cpp_features.proto │ │ │ │ ├── descriptor.proto │ │ │ │ ├── duration.proto │ │ │ │ ├── empty.proto │ │ │ │ ├── field_mask.proto │ │ │ │ ├── go_features.proto │ │ │ │ ├── java_features.proto │ │ │ │ ├── source_context.proto │ │ │ │ ├── struct.proto │ │ │ │ ├── timestamp.proto │ │ │ │ ├── type.proto │ │ │ │ └── wrappers.proto │ │ │ └── readme.txt │ └── registry │ │ ├── consul │ │ ├── client.go │ │ ├── registry.go │ │ ├── registry_test.go │ │ ├── service.go │ │ └── watcher.go │ │ ├── etcd │ │ ├── registry.go │ │ ├── registry_test.go │ │ ├── service.go │ │ └── watcher.go │ │ ├── kubernetes │ │ └── registry.go │ │ ├── nacos │ │ ├── README.md │ │ ├── registry.go │ │ ├── registry_test.go │ │ └── watcher.go │ │ ├── registry.go │ │ └── zookeeper │ │ ├── register.go │ │ ├── register_test.go │ │ ├── service.go │ │ └── watcher.go ├── db │ ├── mysql │ │ ├── mysql_facade.go │ │ └── mysql_mgr.go │ ├── redis │ │ ├── cap_test.go │ │ ├── config.go │ │ └── redis_mgr.go │ ├── ssdb │ │ ├── config.go │ │ ├── ssdb_engin.go │ │ ├── ssdb_mgr.go │ │ └── test.go │ └── xorm │ │ ├── config.go │ │ ├── orm_engin.go │ │ ├── orm_mgr.go │ │ ├── orm_session.go │ │ └── xorm_test.go ├── net │ ├── gnet_server │ │ ├── gnet_udp.go │ │ └── gnet_udp_test.go │ ├── kcp_server │ │ ├── kcp.go │ │ ├── kcp_i.go │ │ └── kcp_test.go │ ├── net_mgr │ │ ├── kcp_impl.go │ │ ├── net_factory.go │ │ ├── net_i.go │ │ ├── tcp_impl.go │ │ └── ws_impl.go │ ├── tcp_server │ │ ├── tcp_i.go │ │ ├── tcp_packet.go │ │ └── tcp_server.go │ └── ws_server │ │ ├── beego_ws.go │ │ ├── gin_ws.go │ │ ├── ws.go │ │ └── ws_i.go ├── service │ ├── algorithm │ │ └── lru_cache.go │ ├── application │ │ ├── app.go │ │ ├── sig.go │ │ └── sig_windows.go │ ├── async │ │ ├── async.go │ │ └── queue.go │ ├── bus │ │ ├── bus_config.go │ │ ├── bus_factory.go │ │ ├── bus_i.go │ │ ├── bus_impl_nsq.go │ │ ├── bus_impl_rmq.go │ │ ├── bus_ip.go │ │ ├── bus_test.go │ │ └── nsq │ │ │ ├── README.md │ │ │ ├── cap_test.go │ │ │ ├── consumer.go │ │ │ └── producer.go │ ├── cache │ │ ├── cache.go │ │ ├── cache_test.go │ │ ├── sharded.go │ │ └── sharded_test.go │ ├── config │ │ └── nacos_config.go │ ├── router │ │ └── router.go │ ├── sensitive_words │ │ ├── sensitive.go │ │ └── sensitive_test.go │ ├── svrinstmgr │ │ └── svr_inst_mgr.go │ └── transaction │ │ ├── transaction_factory.go │ │ ├── transaction_i.go │ │ ├── transaction_impl.go │ │ └── transaction_mgr_impl.go ├── util │ ├── convert │ │ └── common.go │ ├── crypto │ │ ├── aes │ │ │ ├── base.go │ │ │ ├── cbc.go │ │ │ ├── cfb.go │ │ │ └── ecb.go │ │ ├── base64.go │ │ ├── cap_test.go │ │ ├── md5.go │ │ └── xxtea │ │ │ └── xxtea.go │ ├── deps │ │ └── protoc │ │ │ ├── protoc-3.11.4-linux-x86_64 │ │ │ ├── bin │ │ │ │ ├── protoc │ │ │ │ └── protoc-gen-go │ │ │ ├── include │ │ │ │ └── google │ │ │ │ │ └── protobuf │ │ │ │ │ ├── any.proto │ │ │ │ │ ├── api.proto │ │ │ │ │ ├── compiler │ │ │ │ │ └── plugin.proto │ │ │ │ │ ├── descriptor.proto │ │ │ │ │ ├── duration.proto │ │ │ │ │ ├── empty.proto │ │ │ │ │ ├── field_mask.proto │ │ │ │ │ ├── source_context.proto │ │ │ │ │ ├── struct.proto │ │ │ │ │ ├── timestamp.proto │ │ │ │ │ ├── type.proto │ │ │ │ │ └── wrappers.proto │ │ │ └── readme.txt │ │ │ ├── protoc-3.11.4-osx-x86_64 │ │ │ ├── bin │ │ │ │ └── protoc │ │ │ ├── include │ │ │ │ └── google │ │ │ │ │ └── protobuf │ │ │ │ │ ├── any.proto │ │ │ │ │ ├── api.proto │ │ │ │ │ ├── compiler │ │ │ │ │ └── plugin.proto │ │ │ │ │ ├── descriptor.proto │ │ │ │ │ ├── duration.proto │ │ │ │ │ ├── empty.proto │ │ │ │ │ ├── field_mask.proto │ │ │ │ │ ├── source_context.proto │ │ │ │ │ ├── struct.proto │ │ │ │ │ ├── timestamp.proto │ │ │ │ │ ├── type.proto │ │ │ │ │ └── wrappers.proto │ │ │ └── readme.txt │ │ │ └── protoc-3.11.4-win64 │ │ │ ├── include │ │ │ └── google │ │ │ │ └── protobuf │ │ │ │ ├── any.proto │ │ │ │ ├── api.proto │ │ │ │ ├── compiler │ │ │ │ └── plugin.proto │ │ │ │ ├── descriptor.proto │ │ │ │ ├── duration.proto │ │ │ │ ├── empty.proto │ │ │ │ ├── field_mask.proto │ │ │ │ ├── source_context.proto │ │ │ │ ├── struct.proto │ │ │ │ ├── timestamp.proto │ │ │ │ ├── type.proto │ │ │ │ └── wrappers.proto │ │ │ └── readme.txt │ ├── encoding │ │ ├── encoding.go │ │ ├── encoding_test.go │ │ ├── json │ │ │ └── json.go │ │ ├── msgp │ │ │ └── msg_pack.go │ │ ├── proto │ │ │ └── proto.go │ │ ├── xml │ │ │ └── xml.go │ │ └── yaml │ │ │ ├── yaml.go │ │ │ └── yaml_test.go │ ├── file │ │ └── file.go │ ├── generic │ │ └── types.go │ ├── idgen │ │ ├── idgen.go │ │ └── idgen_test.go │ ├── marshal │ │ ├── cap_test.go │ │ └── load.go │ ├── mutex │ │ ├── recursive.go │ │ └── try_lock.go │ ├── random │ │ ├── bytes.go │ │ ├── init.go │ │ ├── rand.go │ │ ├── rand_test.go │ │ └── string.go │ ├── safego │ │ ├── safe_goroutine.go │ │ ├── safe_test.go │ │ └── singleflight.go │ ├── slices │ │ └── slices.go │ ├── timer │ │ └── timewheel.go │ ├── tos │ │ ├── dir.go │ │ ├── port.go │ │ ├── port_test.go │ │ ├── proc.go │ │ └── sysinfo.go │ ├── version │ │ └── version.go │ ├── xlstrans │ │ ├── buid.bat │ │ ├── buid.sh │ │ ├── main.go │ │ ├── parse_struct.go │ │ ├── xls_to_const.go │ │ ├── xls_to_data.go │ │ ├── xls_to_go.go │ │ ├── xls_to_pb.go │ │ └── xls_to_system_unlock.go │ └── zip │ │ ├── cap_test.go │ │ ├── gzip.go │ │ └── zip.go └── web │ ├── http │ └── http_api.go │ ├── rest │ ├── Auth.go │ ├── Captcha.go │ ├── Controller.go │ ├── Crypto.go │ ├── Func.go │ ├── JsonTime.go │ ├── RegUtil.go │ ├── Result.go │ └── SessionUtil.go │ └── web_gin │ ├── config.go │ ├── handler_process.go │ └── http.go ├── main.sh ├── module ├── drop │ └── mymath.go └── misc │ ├── constant.go │ └── func.go ├── readme.md ├── src ├── connsvr │ ├── app.go │ ├── cmd_handler │ │ ├── register.go │ │ └── trans_broadcast.go │ ├── globals │ │ └── globals.go │ ├── login │ │ └── login.go │ ├── main.go │ └── pack_proc.go ├── infosvr │ ├── app.go │ ├── cmd_handler │ │ ├── register.go │ │ └── trans_info.go │ ├── globals │ │ └── globals.go │ ├── info │ │ └── info_mgr.go │ └── main.go ├── mainsvr │ ├── app.go │ ├── cmd_handler │ │ ├── c2s_main_desc.go │ │ ├── c2s_main_login.go │ │ ├── c2s_main_mall.go │ │ ├── c2s_main_teaxs_room.go │ │ ├── register.go │ │ ├── role_adapter.go │ │ └── s2s_main_gm.go │ ├── globals │ │ ├── globals.go │ │ └── rds │ │ │ └── redis.go │ ├── main.go │ ├── role │ │ ├── actvity_task.go │ │ ├── drop.go │ │ ├── game.go │ │ ├── guide.go │ │ ├── icon.go │ │ ├── item.go │ │ ├── mail.go │ │ ├── mall.go │ │ ├── open_function.go │ │ ├── reason.go │ │ ├── role.go │ │ └── role_mgr.go │ └── room │ │ ├── create.go │ │ └── join.go ├── mysqlsvr │ ├── app.go │ ├── cmd_handler │ │ ├── inner_udpate.go │ │ ├── query_room_info.go │ │ ├── register.go │ │ └── trans_mysql.go │ ├── globals │ │ └── globals.go │ ├── main.go │ └── manager │ │ └── table_mgr.go └── roomcentersvr │ ├── app.go │ ├── cmd_handler │ ├── adapter.go │ ├── register.go │ └── s2s_texas_standard.go │ ├── globals │ ├── globals.go │ └── idgen │ │ └── idgen.go │ ├── logic │ ├── quick_start.go │ ├── room_list.go │ └── sort.go │ ├── main.go │ ├── room_ai │ └── ai_creat.go │ └── room_mgr │ ├── base.go │ ├── data_proc.go │ └── texas_room │ ├── base.go │ ├── data_proc.go │ └── texas │ └── base.go └── tools ├── cfgtool ├── domain │ └── define.go ├── internal │ ├── base │ │ ├── func.go │ │ ├── typespec.go │ │ └── util.go │ ├── manager │ │ ├── convert_mgr.go │ │ ├── proto_mgr.go │ │ ├── table_mgr.go │ │ └── type_mgr.go │ ├── parser │ │ ├── parser.go │ │ └── reference.go │ └── templ │ │ ├── code_tpl.go │ │ ├── index_tpl.go │ │ └── proto_tpl.go ├── main.go ├── service │ ├── code_gen.go │ ├── data_gen.go │ ├── index_gen.go │ └── proto_gen.go └── test │ └── tool_test.go └── tester ├── conn_test.go ├── login_test.go ├── rummy_test.go ├── sync_data_test.go ├── t_test.go └── tester_util ├── role.go ├── room.go ├── session.go ├── tester_util.go └── ws_util.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | *.exe 3 | doc/~$服务器技术架构文档.docx 4 | build/* 5 | /logs 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-2015 codingnow.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /common/define/const.go: -------------------------------------------------------------------------------- 1 | package define 2 | 3 | const ( 4 | RoomIdLen = 6 // 房间ID长度 5 | ) 6 | -------------------------------------------------------------------------------- /common/gamedata/data/DropItemConfing.conf: -------------------------------------------------------------------------------- 1 | Ary: < 2 | DropItemId: 10100101 3 | DropId: 90410101 4 | ItemId: 30301101 5 | ItemName: "Nana\347\242\216\347\211\207" 6 | Count: 1 7 | DropWay: 2 8 | Probability: 100 9 | > 10 | Ary: < 11 | DropItemId: 10100102 12 | DropId: 90410101 13 | ItemId: 30301102 14 | ItemName: "\350\212\231\350\225\276\351\233\205\347\242\216\347\211\207" 15 | Count: 1 16 | DropWay: 2 17 | Probability: 50 18 | > 19 | Ary: < 20 | DropItemId: 10100103 21 | DropId: 90410101 22 | ItemId: 30301103 23 | ItemName: "\344\272\232\345\216\206\345\261\261\345\244\247\347\242\216\347\211\207" 24 | Count: 1 25 | DropWay: 2 26 | Probability: 25 27 | > 28 | Ary: < 29 | DropItemId: 10100104 30 | DropId: 90410101 31 | ItemId: 30301106 32 | ItemName: "\347\210\261\344\270\275\344\270\235\347\242\216\347\211\207" 33 | Count: 1 34 | DropWay: 2 35 | Probability: 15 36 | > 37 | Ary: < 38 | DropItemId: 10100105 39 | DropId: 90410101 40 | ItemId: 30301110 41 | ItemName: "\347\273\264\346\213\211\347\242\216\347\211\207" 42 | Count: 1 43 | DropWay: 2 44 | Probability: 5 45 | > 46 | Ary: < 47 | DropItemId: 10100201 48 | DropId: 90103002 49 | ItemId: 10101002 50 | ItemName: "\346\257\217\346\227\245\345\205\215\350\264\271\351\207\221\345\270\201" 51 | Count: 10000 52 | DropWay: 1 53 | > -------------------------------------------------------------------------------- /common/gamedata/data/MachineConfig.conf: -------------------------------------------------------------------------------- 1 | Ary: < 2 | GameId: 1 3 | StartDuration: 15 4 | PreFlopDuration: 20 5 | FlopDuration: 20 6 | TurnDuration: 20 7 | RiverDuration: 20 8 | EndDuration: 10 9 | DefaultDuration: 10 10 | > 11 | Ary: < 12 | GameId: 2 13 | StartDuration: 15 14 | PreFlopDuration: 20 15 | FlopDuration: 20 16 | TurnDuration: 20 17 | RiverDuration: 20 18 | EndDuration: 10 19 | DefaultDuration: 10 20 | > 21 | Ary: < 22 | GameId: 3 23 | StartDuration: 15 24 | PreFlopDuration: 20 25 | FlopDuration: 20 26 | TurnDuration: 20 27 | RiverDuration: 20 28 | EndDuration: 10 29 | DefaultDuration: 10 30 | > 31 | Ary: < 32 | GameId: 4 33 | StartDuration: 15 34 | PreFlopDuration: 20 35 | FlopDuration: 20 36 | TurnDuration: 20 37 | RiverDuration: 20 38 | EndDuration: 10 39 | DefaultDuration: 10 40 | > -------------------------------------------------------------------------------- /common/gamedata/data/TaskConfig.conf: -------------------------------------------------------------------------------- 1 | Ary: < 2 | TaskID: 1 3 | TaskTitle: "\346\227\240\345\220\215\346\260\217" 4 | Reward: < 5 | PropType: PropertyType_Coin 6 | Add: 20 7 | > 8 | Reward: < 9 | PropType: PropertyType_Diamond 10 | Add: 40 11 | > 12 | > -------------------------------------------------------------------------------- /common/gamedata/data/TexasTestConfig.conf: -------------------------------------------------------------------------------- 1 | Ary: < 2 | Round: 1 3 | Publics: "A1" 4 | Publics: "J3" 5 | Publics: "K1" 6 | Publics: "21" 7 | Publics: "31" 8 | Chair1: "A2,J1" 9 | Chair2: "A3,Q1" 10 | Chair3: "A2,J2" 11 | Chair4: "A2,J2" 12 | Chair5: "A3,Q2" 13 | Chair6: "A2,J3" 14 | Chair7: "A2,J3" 15 | Chair8: "A3,Q3" 16 | Chair9: "A2,J4" 17 | Chair10: "A2,J4" 18 | > 19 | Ary: < 20 | Round: 2 21 | Publics: "A1" 22 | Publics: "J3" 23 | Publics: "K1" 24 | Publics: "21" 25 | Publics: "32" 26 | Chair1: "A2,J1" 27 | Chair2: "A3,Q1" 28 | Chair3: "A2,J2" 29 | Chair4: "A2,J2" 30 | Chair5: "A3,Q2" 31 | Chair6: "A2,J3" 32 | Chair7: "A2,J3" 33 | Chair8: "A3,Q3" 34 | Chair9: "A2,J4" 35 | Chair10: "A2,J4" 36 | > 37 | Ary: < 38 | Round: 3 39 | Publics: "A1" 40 | Publics: "J3" 41 | Publics: "K1" 42 | Publics: "21" 43 | Publics: "33" 44 | Chair1: "A2,J1" 45 | Chair2: "A3,Q1" 46 | Chair3: "A2,J2" 47 | Chair4: "A2,J2" 48 | Chair5: "A3,Q2" 49 | Chair6: "A2,J3" 50 | Chair7: "A2,J3" 51 | Chair8: "A3,Q3" 52 | Chair9: "A2,J4" 53 | Chair10: "A2,J4" 54 | > 55 | Ary: < 56 | Round: 4 57 | Publics: "A1" 58 | Publics: "J3" 59 | Publics: "K1" 60 | Publics: "21" 61 | Publics: "34" 62 | Chair1: "A2,J1" 63 | Chair2: "A3,Q1" 64 | Chair3: "A2,J2" 65 | Chair4: "A2,J2" 66 | Chair5: "A3,Q2" 67 | Chair6: "A2,J3" 68 | Chair7: "A2,J3" 69 | Chair8: "A3,Q3" 70 | Chair9: "A2,J4" 71 | Chair10: "A2,J4" 72 | > -------------------------------------------------------------------------------- /common/gamedata/gamedata_test.go: -------------------------------------------------------------------------------- 1 | package gamedata 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/go-zookeeper/zk" 8 | ) 9 | 10 | func TestMain(m *testing.M) { 11 | if err := InitLocal("./data"); err != nil { 12 | panic(err) 13 | } 14 | 15 | m.Run() 16 | } 17 | 18 | func TestZK(t *testing.T) { 19 | zkConn, chanConnect, err := zk.Connect([]string{"192.168.50.11:2182"}, time.Second*30) 20 | t.Log(err, zkConn, chanConnect) 21 | } 22 | -------------------------------------------------------------------------------- /common/gamedata/repository/global_config/GlobalData.gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 本代码由xlsx工具生成,请勿手动修改 3 | */ 4 | 5 | package global_config 6 | 7 | import ( 8 | "sync/atomic" 9 | 10 | "github.com/Iori372552686/GoOne/common/gamedata" 11 | protocol "github.com/Iori372552686/game_protocol/protocol" 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var obj = atomic.Value{} 16 | 17 | type GlobalConfigData struct { 18 | _List []*protocol.GlobalConfig 19 | _Name map[string]*protocol.GlobalConfig 20 | } 21 | 22 | // 注册函数 23 | func init() { 24 | gamedata.Register("GlobalConfig", parse) 25 | } 26 | 27 | func parse(buf string) error { 28 | data := &protocol.GlobalConfigAry{} 29 | if err := proto.UnmarshalText(buf, data); err != nil { 30 | return err 31 | } 32 | 33 | _Name := make(map[string]*protocol.GlobalConfig) 34 | for _, item := range data.Ary { 35 | _Name[item.Name] = item 36 | } 37 | 38 | obj.Store(&GlobalConfigData{ 39 | _List: data.Ary, 40 | _Name: _Name, 41 | }) 42 | return nil 43 | } 44 | 45 | func GetHead() *protocol.GlobalConfig { 46 | obj, ok := obj.Load().(*GlobalConfigData) 47 | if !ok { 48 | return nil 49 | } 50 | return obj._List[0] 51 | } 52 | 53 | func GetAll() (rets []*protocol.GlobalConfig) { 54 | obj, ok := obj.Load().(*GlobalConfigData) 55 | if !ok { 56 | return 57 | } 58 | rets = make([]*protocol.GlobalConfig, len(obj._List)) 59 | copy(rets, obj._List) 60 | return 61 | } 62 | 63 | func Range(f func(*protocol.GlobalConfig) bool) { 64 | obj, ok := obj.Load().(*GlobalConfigData) 65 | if !ok { 66 | return 67 | } 68 | for _, item := range obj._List { 69 | if !f(item) { 70 | return 71 | } 72 | } 73 | } 74 | 75 | func GetByName(Name string) *protocol.GlobalConfig { 76 | obj, ok := obj.Load().(*GlobalConfigData) 77 | if !ok { 78 | return nil 79 | } 80 | 81 | if val, ok := obj._Name[Name]; ok { 82 | return val 83 | } 84 | return nil 85 | } 86 | -------------------------------------------------------------------------------- /common/gamedata/repository/item_config/ItemData.gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 本代码由xlsx工具生成,请勿手动修改 3 | */ 4 | 5 | package item_config 6 | 7 | import ( 8 | "sync/atomic" 9 | 10 | "github.com/Iori372552686/GoOne/common/gamedata" 11 | protocol "github.com/Iori372552686/game_protocol/protocol" 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var obj = atomic.Value{} 16 | 17 | type ItemConfigData struct { 18 | _List []*protocol.ItemConfig 19 | _ItemId map[int32]*protocol.ItemConfig 20 | } 21 | 22 | // 注册函数 23 | func init() { 24 | gamedata.Register("ItemConfig", parse) 25 | } 26 | 27 | func parse(buf string) error { 28 | data := &protocol.ItemConfigAry{} 29 | if err := proto.UnmarshalText(buf, data); err != nil { 30 | return err 31 | } 32 | 33 | _ItemId := make(map[int32]*protocol.ItemConfig) 34 | for _, item := range data.Ary { 35 | _ItemId[item.ItemId] = item 36 | } 37 | 38 | obj.Store(&ItemConfigData{ 39 | _List: data.Ary, 40 | _ItemId: _ItemId, 41 | }) 42 | return nil 43 | } 44 | 45 | func GetHead() *protocol.ItemConfig { 46 | obj, ok := obj.Load().(*ItemConfigData) 47 | if !ok { 48 | return nil 49 | } 50 | return obj._List[0] 51 | } 52 | 53 | func GetAll() (rets []*protocol.ItemConfig) { 54 | obj, ok := obj.Load().(*ItemConfigData) 55 | if !ok { 56 | return 57 | } 58 | rets = make([]*protocol.ItemConfig, len(obj._List)) 59 | copy(rets, obj._List) 60 | return 61 | } 62 | 63 | func Range(f func(*protocol.ItemConfig) bool) { 64 | obj, ok := obj.Load().(*ItemConfigData) 65 | if !ok { 66 | return 67 | } 68 | for _, item := range obj._List { 69 | if !f(item) { 70 | return 71 | } 72 | } 73 | } 74 | 75 | func GetByItemId(ItemId int32) *protocol.ItemConfig { 76 | obj, ok := obj.Load().(*ItemConfigData) 77 | if !ok { 78 | return nil 79 | } 80 | 81 | if val, ok := obj._ItemId[ItemId]; ok { 82 | return val 83 | } 84 | return nil 85 | } 86 | -------------------------------------------------------------------------------- /common/gamedata/repository/machine_config/MachineData.gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 本代码由xlsx工具生成,请勿手动修改 3 | */ 4 | 5 | package machine_config 6 | 7 | import ( 8 | "sync/atomic" 9 | 10 | "github.com/Iori372552686/GoOne/common/gamedata" 11 | protocol "github.com/Iori372552686/game_protocol/protocol" 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var obj = atomic.Value{} 16 | 17 | type MachineConfigData struct { 18 | _List []*protocol.MachineConfig 19 | _GameId map[int32]*protocol.MachineConfig 20 | } 21 | 22 | // 注册函数 23 | func init() { 24 | gamedata.Register("MachineConfig", parse) 25 | } 26 | 27 | func parse(buf string) error { 28 | data := &protocol.MachineConfigAry{} 29 | if err := proto.UnmarshalText(buf, data); err != nil { 30 | return err 31 | } 32 | 33 | _GameId := make(map[int32]*protocol.MachineConfig) 34 | for _, item := range data.Ary { 35 | _GameId[item.GameId] = item 36 | } 37 | 38 | obj.Store(&MachineConfigData{ 39 | _List: data.Ary, 40 | _GameId: _GameId, 41 | }) 42 | return nil 43 | } 44 | 45 | func GetHead() *protocol.MachineConfig { 46 | obj, ok := obj.Load().(*MachineConfigData) 47 | if !ok { 48 | return nil 49 | } 50 | return obj._List[0] 51 | } 52 | 53 | func GetAll() (rets []*protocol.MachineConfig) { 54 | obj, ok := obj.Load().(*MachineConfigData) 55 | if !ok { 56 | return 57 | } 58 | rets = make([]*protocol.MachineConfig, len(obj._List)) 59 | copy(rets, obj._List) 60 | return 61 | } 62 | 63 | func Range(f func(*protocol.MachineConfig) bool) { 64 | obj, ok := obj.Load().(*MachineConfigData) 65 | if !ok { 66 | return 67 | } 68 | for _, item := range obj._List { 69 | if !f(item) { 70 | return 71 | } 72 | } 73 | } 74 | 75 | func GetByGameId(GameId int32) *protocol.MachineConfig { 76 | obj, ok := obj.Load().(*MachineConfigData) 77 | if !ok { 78 | return nil 79 | } 80 | 81 | if val, ok := obj._GameId[GameId]; ok { 82 | return val 83 | } 84 | return nil 85 | } 86 | -------------------------------------------------------------------------------- /common/gamedata/repository/mall_config/MallData.gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 本代码由xlsx工具生成,请勿手动修改 3 | */ 4 | 5 | package mall_config 6 | 7 | import ( 8 | "sync/atomic" 9 | 10 | "github.com/Iori372552686/GoOne/common/gamedata" 11 | protocol "github.com/Iori372552686/game_protocol/protocol" 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var obj = atomic.Value{} 16 | 17 | type MallConfigData struct { 18 | _List []*protocol.MallConfig 19 | _Id map[int32]*protocol.MallConfig 20 | } 21 | 22 | // 注册函数 23 | func init() { 24 | gamedata.Register("MallConfig", parse) 25 | } 26 | 27 | func parse(buf string) error { 28 | data := &protocol.MallConfigAry{} 29 | if err := proto.UnmarshalText(buf, data); err != nil { 30 | return err 31 | } 32 | 33 | _Id := make(map[int32]*protocol.MallConfig) 34 | for _, item := range data.Ary { 35 | _Id[item.Id] = item 36 | } 37 | 38 | obj.Store(&MallConfigData{ 39 | _List: data.Ary, 40 | _Id: _Id, 41 | }) 42 | return nil 43 | } 44 | 45 | func GetHead() *protocol.MallConfig { 46 | obj, ok := obj.Load().(*MallConfigData) 47 | if !ok { 48 | return nil 49 | } 50 | return obj._List[0] 51 | } 52 | 53 | func GetAll() (rets []*protocol.MallConfig) { 54 | obj, ok := obj.Load().(*MallConfigData) 55 | if !ok { 56 | return 57 | } 58 | rets = make([]*protocol.MallConfig, len(obj._List)) 59 | copy(rets, obj._List) 60 | return 61 | } 62 | 63 | func Range(f func(*protocol.MallConfig) bool) { 64 | obj, ok := obj.Load().(*MallConfigData) 65 | if !ok { 66 | return 67 | } 68 | for _, item := range obj._List { 69 | if !f(item) { 70 | return 71 | } 72 | } 73 | } 74 | 75 | func GetById(Id int32) *protocol.MallConfig { 76 | obj, ok := obj.Load().(*MallConfigData) 77 | if !ok { 78 | return nil 79 | } 80 | 81 | if val, ok := obj._Id[Id]; ok { 82 | return val 83 | } 84 | return nil 85 | } 86 | -------------------------------------------------------------------------------- /common/gamedata/repository/recharge_config/RechargeData.gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 本代码由xlsx工具生成,请勿手动修改 3 | */ 4 | 5 | package recharge_config 6 | 7 | import ( 8 | "sync/atomic" 9 | 10 | "github.com/Iori372552686/GoOne/common/gamedata" 11 | protocol "github.com/Iori372552686/game_protocol/protocol" 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var obj = atomic.Value{} 16 | 17 | type RechargeConfigData struct { 18 | _List []*protocol.RechargeConfig 19 | _Id map[int32]*protocol.RechargeConfig 20 | } 21 | 22 | // 注册函数 23 | func init() { 24 | gamedata.Register("RechargeConfig", parse) 25 | } 26 | 27 | func parse(buf string) error { 28 | data := &protocol.RechargeConfigAry{} 29 | if err := proto.UnmarshalText(buf, data); err != nil { 30 | return err 31 | } 32 | 33 | _Id := make(map[int32]*protocol.RechargeConfig) 34 | for _, item := range data.Ary { 35 | _Id[item.Id] = item 36 | } 37 | 38 | obj.Store(&RechargeConfigData{ 39 | _List: data.Ary, 40 | _Id: _Id, 41 | }) 42 | return nil 43 | } 44 | 45 | func GetHead() *protocol.RechargeConfig { 46 | obj, ok := obj.Load().(*RechargeConfigData) 47 | if !ok { 48 | return nil 49 | } 50 | return obj._List[0] 51 | } 52 | 53 | func GetAll() (rets []*protocol.RechargeConfig) { 54 | obj, ok := obj.Load().(*RechargeConfigData) 55 | if !ok { 56 | return 57 | } 58 | rets = make([]*protocol.RechargeConfig, len(obj._List)) 59 | copy(rets, obj._List) 60 | return 61 | } 62 | 63 | func Range(f func(*protocol.RechargeConfig) bool) { 64 | obj, ok := obj.Load().(*RechargeConfigData) 65 | if !ok { 66 | return 67 | } 68 | for _, item := range obj._List { 69 | if !f(item) { 70 | return 71 | } 72 | } 73 | } 74 | 75 | func GetById(Id int32) *protocol.RechargeConfig { 76 | obj, ok := obj.Load().(*RechargeConfigData) 77 | if !ok { 78 | return nil 79 | } 80 | 81 | if val, ok := obj._Id[Id]; ok { 82 | return val 83 | } 84 | return nil 85 | } 86 | -------------------------------------------------------------------------------- /common/gamedata/repository/task_config/TaskData.gen.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 本代码由xlsx工具生成,请勿手动修改 3 | */ 4 | 5 | package task_config 6 | 7 | import ( 8 | "sync/atomic" 9 | 10 | "github.com/Iori372552686/GoOne/common/gamedata" 11 | protocol "github.com/Iori372552686/game_protocol/protocol" 12 | "github.com/golang/protobuf/proto" 13 | ) 14 | 15 | var obj = atomic.Value{} 16 | 17 | type TaskConfigData struct { 18 | _List []*protocol.TaskConfig 19 | _TaskID map[uint32]*protocol.TaskConfig 20 | } 21 | 22 | // 注册函数 23 | func init() { 24 | gamedata.Register("TaskConfig", parse) 25 | } 26 | 27 | func parse(buf string) error { 28 | data := &protocol.TaskConfigAry{} 29 | if err := proto.UnmarshalText(buf, data); err != nil { 30 | return err 31 | } 32 | 33 | _TaskID := make(map[uint32]*protocol.TaskConfig) 34 | for _, item := range data.Ary { 35 | _TaskID[item.TaskID] = item 36 | } 37 | 38 | obj.Store(&TaskConfigData{ 39 | _List: data.Ary, 40 | _TaskID: _TaskID, 41 | }) 42 | return nil 43 | } 44 | 45 | func GetHead() *protocol.TaskConfig { 46 | obj, ok := obj.Load().(*TaskConfigData) 47 | if !ok { 48 | return nil 49 | } 50 | return obj._List[0] 51 | } 52 | 53 | func GetAll() (rets []*protocol.TaskConfig) { 54 | obj, ok := obj.Load().(*TaskConfigData) 55 | if !ok { 56 | return 57 | } 58 | rets = make([]*protocol.TaskConfig, len(obj._List)) 59 | copy(rets, obj._List) 60 | return 61 | } 62 | 63 | func Range(f func(*protocol.TaskConfig) bool) { 64 | obj, ok := obj.Load().(*TaskConfigData) 65 | if !ok { 66 | return 67 | } 68 | for _, item := range obj._List { 69 | if !f(item) { 70 | return 71 | } 72 | } 73 | } 74 | 75 | func GetByTaskID(TaskID uint32) *protocol.TaskConfig { 76 | obj, ok := obj.Load().(*TaskConfigData) 77 | if !ok { 78 | return nil 79 | } 80 | 81 | if val, ok := obj._TaskID[TaskID]; ok { 82 | return val 83 | } 84 | return nil 85 | } 86 | -------------------------------------------------------------------------------- /common/gfunc/game_func.go: -------------------------------------------------------------------------------- 1 | package gfunc 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "github.com/Iori372552686/GoOne/common/define" 7 | "github.com/Iori372552686/GoOne/lib/api/logger" 8 | pb "github.com/Iori372552686/game_protocol/protocol" 9 | "github.com/cespare/xxhash/v2" 10 | "strconv" 11 | ) 12 | 13 | // CRC32(32 位)冲突概率 ≈ 50% 当生成 7.7 万个 ID 时(生日问题) 14 | // xxHash(64 位)冲突概率 ≈ 50% 当生成 50 亿个 ID 时 15 | // 实际应根据业务量选择: 16 | // 中小规模(<1M ID/天):CRC32 足够 17 | // 超大规模:推荐 xxHash 或 SHA1 截断 18 | func GenerateRoomId(iDGen uint64) uint64 { 19 | buf := make([]byte, 8) 20 | binary.BigEndian.PutUint64(buf, iDGen) 21 | //hash := uint64(crc32.ChecksumIEEE(buf)) // 生成 32 位哈希,crc32 算法 22 | strHash := fmt.Sprintf("%d", xxhash.Sum64(buf)) 23 | roomID, _ := strconv.ParseUint(strHash[:define.RoomIdLen], 10, 64) 24 | return roomID 25 | } 26 | 27 | // GetTexasRoomListIndex 获取德州房间列表索引 28 | func GetTexasRoomListIndex(zone uint32, gameId pb.GameTypeId, coin pb.CoinType) uint64 { 29 | logger.Infof("GetTexasRoomListIndex zone:%v gameId:%v coin:%v", zone, gameId, coin) 30 | return uint64(gameId)*10000 + uint64(zone)*10 + uint64(coin) 31 | } 32 | -------------------------------------------------------------------------------- /deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -x 3 | 4 | ENV=$1 5 | OPTION=$2 6 | 7 | usage() 8 | { 9 | echo "Usage: $0 [role names]..." 10 | echo "Example: $0 dev1 push mainsvr connsvr // push file of mainsvr and connsvr" 11 | echo " $0 dev1 init // init all server, no role indicated means all roles" 12 | } 13 | 14 | if [[ $# < 2 ]]; then 15 | usage 16 | exit 1 17 | fi 18 | 19 | #所有的role 20 | ALL_TARGET_ROLES=("commconf" "gamedata" "connsvr" "mainsvr" "infosvr" "mysqlsvr" "gamesvr" "mailsvr" "friendsvr" "chatsvr" "ranksvr" "guildsvr" "roomcentersvr" "texassvr") 21 | 22 | #如果命令行没有指明role,则默认为所有role 23 | target_role=() 24 | if [[ $# < 3 ]]; then 25 | target_role=(`echo ${ALL_TARGET_ROLES[*]}`) 26 | else 27 | for ((i=3;i<=$#;i++)); 28 | do 29 | target_role[${#target_role[@]}]=${!i} 30 | done 31 | fi 32 | 33 | #计算tags 34 | target="" 35 | for i in "${!target_role[@]}"; 36 | do 37 | #最前面不用添加逗号 38 | if [[ $i != 0 ]]; then 39 | target="$target," 40 | fi 41 | target="$target${target_role[$i]}_$OPTION" 42 | done 43 | 44 | #如果没有tags,则在ansible后面不添加--tags标签 45 | tags="--tags $target" 46 | if [[ $target == "" ]]; then 47 | tags="" 48 | fi 49 | 50 | #由于在子目录运行playbook会有目录结构问题,所以建个临时文件 51 | rand=$RANDOM 52 | TMP=.tmp${rand}.myl 53 | cp playbook_dev/${ENV}.yml ${TMP} 54 | #执行playbook 55 | ansible-playbook -i hosts/host_dev.txt ${TMP} $tags 56 | rm ${TMP} 57 | 58 | -------------------------------------------------------------------------------- /deploy/hosts/host_dev.txt: -------------------------------------------------------------------------------- 1 | [dev1] 2 | 192.168.50.250 ansible_ssh_user=root ansible_ssh_pass=root ansible_sudo_pass=123456 ansible_python_interpreter=/usr/bin/python3 ansible_python_path=/usr/lib/python3/dist-packages 3 | 4 | [dev2] 5 | 13.203.103.190 ansible_connection=ssh ansible_ssh_user=ec2-user ansible_ssh_private_key_file=~/.ssh/id_ed25519 ansible_python_interpreter=/usr/bin/python3 ansible_python_path=/usr/lib/python3/dist-packages 6 | 7 | [dev_local] 8 | 127.0.0.1 ansible_ssh_user=user00 ansible_ssh_pass=Iori@123 ansible_sudo_pass=Iori@123 9 | 10 | -------------------------------------------------------------------------------- /deploy/inithost/host.txt: -------------------------------------------------------------------------------- 1 | [dst] 2 | 192.168.50.250 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_sudo_pass=123456 ansible_python_interpreter=/usr/bin/python3 ansible_python_path=/usr/lib/python3/dist-packages 3 | 4 | 5 | 6 | # -------------- tips----------- 7 | # 8 | # ansible-playbook -i host.txt inithost.yml 9 | # 10 | # 默认使用的是ubuntu版本的yml,centos 可选择对应yml 11 | # 12 | # ------------------------------- 13 | -------------------------------------------------------------------------------- /deploy/inithost/init_centos_bak.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: dst 3 | vars: 4 | password: 'Iori@123' 5 | tasks: 6 | # 1.用户 7 | - name: PokerGo 8 | user: 9 | name: PokerGo 10 | group: wheel 11 | password: "{{ password | password_hash('sha512') }}" 12 | shell: /bin/bash 13 | generate_ssh_key: yes 14 | ssh_key_bits: 4096 15 | ssh_key_file: .ssh/id_rsa 16 | # 2.依赖库 17 | - yum: { state: present, name: [libunwind-devel, epel-release, vim, net-tools, crontabs, psmisc, at, rsync, iproute, daemonize] } 18 | # 3.系统设置 19 | # 修改相关限制 20 | - pam_limits: { domain: PokerGo, limit_type: soft, limit_item: core, value: 1000000000} 21 | - pam_limits: { domain: PokerGo, limit_type: hard, limit_item: core, value: 1000000000} 22 | - pam_limits: { domain: PokerGo, limit_type: soft, limit_item: nofile, value: 100000} 23 | - pam_limits: { domain: PokerGo, limit_type: hard, limit_item: nofile, value: 100000} 24 | # 创建core文件存放目录 25 | - file: 26 | path: /data/PokerGo/cores/ 27 | owner: PokerGo 28 | group: wheel 29 | state: directory 30 | # 修改core文件位置 31 | - sysctl: 32 | name: kernel.core_pattern 33 | value: /data/PokerGo/cores/core_%e_%p 34 | sysctl_set: yes 35 | state: present 36 | reload: yes -------------------------------------------------------------------------------- /deploy/playbook_dev/dev1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # 用法: 3 | # 由于ansible的文件夹层级关系,这个playbook实际运行时是被复制到上层文件夹来执行的 4 | # vars:变量,主要定义机器的instanceID, 用于生成实例的唯一busID,进程实例busID的规则是:[worldID].[zoneID].[instanceType].[instanceID] 5 | # vars_file: 变量文件,里面的变量用于替换进程实例配置文件中的变量,比如redis地址mysql地址等等 6 | # roles: 机器上安装的实例类型,除了commconf,gamedata是配置文件之外,其余的都是进程实例 7 | 8 | - hosts: dev1 9 | vars: 10 | - instance_id: 1 11 | vars_files: 12 | - playbook_dev/dev1_vars 13 | roles: 14 | - commconf 15 | - gamedata 16 | - connsvr 17 | - mainsvr 18 | - texassvr 19 | - infosvr 20 | - mysqlsvr 21 | - roomcentersvr 22 | # - mailsvr 23 | # - friendsvr 24 | # - chatsvr 25 | 26 | #关于如何将svr部署到多台机器,可以参照如下方式 27 | #- hosts: test_host1 28 | # vars: 29 | # - instance_id: 1 30 | # vars_files: 31 | # - playbook_dev/test_vars 32 | # roles: 33 | # - commconf 34 | # - gamedata 35 | # - connsvr 36 | # - mainsvr 37 | # - dbsvr 38 | # 39 | #- hosts: test_host2 40 | # vars: 41 | # - instance_id: 2 #这里需要和test_host1的id不一样,不然就会生成相同的实例busID 42 | # vars_files: 43 | # - playbook_dev/test_vars 44 | # roles: 45 | # - commconf #每台机器都需要 46 | # - gamedata #每台机器都需要 47 | # - mainsvr #在test_host1中也有mainsvr,也就是说mainsvr在test集群上部署了2个实例,busID分别为1.1.2.1和1.1.2.2 48 | # - dbsvr 49 | # - rcmdsvr 50 | # - infosvr 51 | # - mysqlsvr 52 | -------------------------------------------------------------------------------- /deploy/playbook_dev/dev1_vars: -------------------------------------------------------------------------------- 1 | root_path: /data/PokerGo 2 | zk_address: 127.0.0.1:2181 3 | rabbitmq_address: amqp://guest:guest@127.0.0.1:5672/ 4 | mongodb_ip: 127.0.0.1 5 | mongodb_port: 27017 6 | redis_ip: 127.0.0.1 7 | redis_port: 6379 8 | redis_passwd: 123456 9 | redis_use_cluster: "false" 10 | mysql_ip: 127.0.0.1 11 | mysql_port: 3306 12 | mysql_user: root 13 | mysql_password: syx123456 14 | mysql_schema: poker 15 | gm_open : "true" 16 | LoginSdkAddr : http://192.168.50.250:8000/mg/api/sdk/getGameRole? 17 | ListenPort : 11000 18 | 19 | -------------------------------------------------------------------------------- /deploy/playbook_dev/dev2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # 用法: 3 | # 由于ansible的文件夹层级关系,这个playbook实际运行时是被复制到上层文件夹来执行的 4 | # vars:变量,主要定义机器的instanceID, 用于生成实例的唯一busID,进程实例busID的规则是:[worldID].[zoneID].[instanceType].[instanceID] 5 | # vars_file: 变量文件,里面的变量用于替换进程实例配置文件中的变量,比如redis地址mysql地址等等 6 | # roles: 机器上安装的实例类型,除了commconf,gamedata是配置文件之外,其余的都是进程实例 7 | 8 | - hosts: dev2 9 | vars: 10 | - instance_id: 1 11 | vars_files: 12 | - playbook_dev/dev2_vars 13 | roles: 14 | - commconf 15 | - gamedata 16 | - connsvr 17 | - mainsvr 18 | - texassvr 19 | - infosvr 20 | - mysqlsvr 21 | - roomcentersvr 22 | # - mailsvr 23 | # - friendsvr 24 | # - chatsvr 25 | 26 | #关于如何将svr部署到多台机器,可以参照如下方式 27 | #- hosts: test_host1 28 | # vars: 29 | # - instance_id: 1 30 | # vars_files: 31 | # - playbook_dev/test_vars 32 | # roles: 33 | # - commconf 34 | # - gamedata 35 | # - connsvr 36 | # - mainsvr 37 | # - dbsvr 38 | # 39 | #- hosts: test_host2 40 | # vars: 41 | # - instance_id: 2 #这里需要和test_host1的id不一样,不然就会生成相同的实例busID 42 | # vars_files: 43 | # - playbook_dev/test_vars 44 | # roles: 45 | # - commconf #每台机器都需要 46 | # - gamedata #每台机器都需要 47 | # - mainsvr #在test_host1中也有mainsvr,也就是说mainsvr在test集群上部署了2个实例,busID分别为1.1.2.1和1.1.2.2 48 | # - dbsvr 49 | # - rcmdsvr 50 | # - infosvr 51 | # - mysqlsvr 52 | -------------------------------------------------------------------------------- /deploy/playbook_dev/dev2_vars: -------------------------------------------------------------------------------- 1 | root_path: /data/PokerGo 2 | zk_address: 127.0.0.1:2181 3 | rabbitmq_address: amqp://guest:guest@127.0.0.1:5672/ 4 | redis_ip: 127.0.0.1 5 | redis_port: 6379 6 | redis_passwd: 123456 7 | redis_use_cluster: "false" 8 | mysql_ip: 127.0.0.1 9 | mysql_port: 3306 10 | mysql_user: user00 11 | mysql_password: Iori@123 12 | mysql_schema: poker_game 13 | gm_open : "true" 14 | LoginSdkAddr : https://systemapi.acewinchip.com/mg/api/sdk/getGameRole? 15 | ListenPort : 11000 16 | 17 | -------------------------------------------------------------------------------- /deploy/playbook_dev/dev_local.yml: -------------------------------------------------------------------------------- 1 | --- 2 | #deploy dev 3 | 4 | - hosts: dev_local 5 | vars: 6 | - instance_id: 1 7 | vars_files: 8 | - playbook_dev/dev_local_vars 9 | roles: 10 | - commconf 11 | - gamedata 12 | - connsvr 13 | - mainsvr 14 | - dbsvr 15 | - infosvr 16 | - mysqlsvr 17 | - opvpsvr 18 | - mailsvr 19 | - friendsvr 20 | - chatsvr -------------------------------------------------------------------------------- /deploy/playbook_dev/dev_local_vars: -------------------------------------------------------------------------------- 1 | root_path: /home/user00/g1 2 | zk_address: 127.0.0.1:2181 3 | rabbitmq_address: amqp://guest:guest@127.0.0.1:5672/ 4 | redis_ip: 127.0.0.1 5 | redis_port: 6379 6 | redis_use_cluster: "false" 7 | mongodb_ip: 127.0.0.1 8 | mongodb_port: 27017 9 | mysql_ip: 192.168.0.81 10 | mysql_port: 3306 11 | mysql_user: user00 12 | mysql_password: Iori@123 13 | mysql_schema: g1 14 | gm_open : "true" 15 | LoginSdkAddr : http://192.168.2.80:8090 16 | -------------------------------------------------------------------------------- /deploy/roles/chatsvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[chatsvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/chatsvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/chatsvr 13 | tags: 'chatsvr_init' 14 | - name: '[chatsvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/chatsvr/server.sh 18 | mode: '0755' 19 | tags: "chatsvr_init" 20 | 21 | - name: '[chatsvr] Copy bin' 22 | copy: 23 | src: ../build/chatsvr 24 | dest: /data/PokerGo/chatsvr/chatsvr 25 | mode: '755' 26 | backup: yes 27 | tags: "chatsvr_push" 28 | 29 | - name: '[chatsvr] start chatsvr' 30 | shell: cd /data/PokerGo/chatsvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'chatsvr_start' 33 | 34 | - name: '[chatsvr] stop chatsvr' 35 | shell: cd /data/PokerGo/chatsvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'chatsvr_stop' 38 | 39 | - name: '[chatsvr] restart chatsvr' 40 | shell: cd /data/PokerGo/chatsvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'chatsvr_restart' 43 | 44 | - name: '[chatsvr] check chatsvr' 45 | shell: cd /data/PokerGo/chatsvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'chatsvr_check' 48 | 49 | - name: '[chatsvr] delLog chatsvr' 50 | shell: cd /data/PokerGo/logs/chatsvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'chatsvr_delLog' 53 | -------------------------------------------------------------------------------- /deploy/roles/commconf/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[commconf] Create a directory if it does not exist' 4 | file: 5 | path: /data/PokerGo/commconf/ 6 | state: directory 7 | mode: '0755' 8 | tags: 'commconf_init' 9 | 10 | - name: '[commconf] Copy files' 11 | copy: 12 | src: ../common/conf/ 13 | dest: /data/PokerGo/commconf/ 14 | tags: "commconf_push" 15 | 16 | - name: '[commconf] Copy game config' 17 | template: 18 | src: server_conf.yaml 19 | dest: /data/PokerGo/commconf/server_conf.yaml 20 | tags: 'commconf_push' -------------------------------------------------------------------------------- /deploy/roles/connsvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[connsvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/connsvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/connsvr 13 | tags: 'connsvr_init' 14 | - name: '[connsvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/connsvr/server.sh 18 | mode: '0755' 19 | tags: "connsvr_init" 20 | 21 | 22 | - name: '[connsvr] Copy bin' 23 | copy: 24 | src: ../build/connsvr 25 | dest: /data/PokerGo/connsvr/connsvr 26 | mode: '0755' 27 | backup: yes 28 | tags: "connsvr_push" 29 | 30 | - name: '[connsvr] start connsvr' 31 | shell: cd /data/PokerGo/connsvr; ./server.sh start; ./server.sh check 32 | ignore_errors: yes 33 | tags: 'connsvr_start' 34 | 35 | - name: '[connsvr] stop connsvr' 36 | shell: cd /data/PokerGo/connsvr; ./server.sh stop 37 | ignore_errors: yes 38 | tags: 'connsvr_stop' 39 | 40 | - name: '[connsvr] restart connsvr' 41 | shell: cd /data/PokerGo/connsvr; ./server.sh restart; ./server.sh check 42 | ignore_errors: yes 43 | tags: 'connsvr_restart' 44 | 45 | - name: '[connsvr] check connsvr' 46 | shell: cd /data/PokerGo/connsvr; ./server.sh check 47 | ignore_errors: yes 48 | tags: 'connsvr_check' 49 | 50 | - name: '[connsvr] delLog connsvr' 51 | shell: cd /data/PokerGo/logss/connsvr; rm ./* 52 | ignore_errors: yes 53 | tags: 'connsvr_delLog' 54 | -------------------------------------------------------------------------------- /deploy/roles/friendsvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[friendsvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/friendsvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/friendsvr 13 | tags: 'friendsvr_init' 14 | - name: '[friendsvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/friendsvr/server.sh 18 | mode: '0755' 19 | tags: "friendsvr_init" 20 | 21 | - name: '[friendsvr] Copy bin' 22 | copy: 23 | src: ../build/friendsvr 24 | dest: /data/PokerGo/friendsvr/friendsvr 25 | mode: '755' 26 | backup: yes 27 | tags: "friendsvr_push" 28 | 29 | - name: '[friendsvr] start friendsvr' 30 | shell: cd /data/PokerGo/friendsvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'friendsvr_start' 33 | 34 | - name: '[friendsvr] stop friendsvr' 35 | shell: cd /data/PokerGo/friendsvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'friendsvr_stop' 38 | 39 | - name: '[friendsvr] restart friendsvr' 40 | shell: cd /data/PokerGo/friendsvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'friendsvr_restart' 43 | 44 | - name: '[friendsvr] check friendsvr' 45 | shell: cd /data/PokerGo/friendsvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'friendsvr_check' 48 | 49 | - name: '[friendsvr] delLog friendsvr' 50 | shell: cd /data/PokerGo/logs/friendsvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'friendsvr_delLog' -------------------------------------------------------------------------------- /deploy/roles/gamedata/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: '[gamedata] Create a directory if it does not exist' 3 | file: 4 | path: '{{ item }}' 5 | state: directory 6 | mode: '0755' 7 | with_items: 8 | - /data/PokerGo/ 9 | - /data/PokerGo/gamedata/ 10 | tags: 'gamedata_init' 11 | 12 | - name: '[gamedata] Gen tar ball' 13 | shell: cd ../common/gamedata/data; tar cvf gamedata.tar --transform s=data/== ./* 14 | connection: local 15 | tags: "gamedata_push" 16 | 17 | - name: '[gamedata] Copy gamedata tar ball' 18 | copy: 19 | src: ../common/gamedata/data/gamedata.tar 20 | dest: /data/PokerGo/gamedata.tar 21 | tags: "gamedata_push" 22 | 23 | - name: '[gamedata] unzip gamedata tar ball' 24 | shell: cd /data/PokerGo/; tar xvf gamedata.tar -C ./gamedata; rm gamedata.tar 25 | ignore_errors: yes 26 | tags: 'gamedata_push' 27 | 28 | - name: '[gamedata] delLog gamedata' 29 | shell: cd /data/PokerGo/logs/gamedata; rm ./* 30 | ignore_errors: yes 31 | tags: 'gamedata_delLog' 32 | -------------------------------------------------------------------------------- /deploy/roles/infosvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[infosvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/infosvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/infosvr 13 | tags: 'infosvr_init' 14 | - name: '[infosvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/infosvr/server.sh 18 | mode: '0755' 19 | tags: "infosvr_init" 20 | 21 | - name: '[infosvr] Copy bin' 22 | copy: 23 | src: ../build/infosvr 24 | dest: /data/PokerGo/infosvr/infosvr 25 | mode: '755' 26 | backup: yes 27 | tags: "infosvr_push" 28 | 29 | - name: '[infosvr] start infosvr' 30 | shell: cd /data/PokerGo/infosvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'infosvr_start' 33 | 34 | - name: '[infosvr] stop infosvr' 35 | shell: cd /data/PokerGo/infosvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'infosvr_stop' 38 | 39 | - name: '[infosvr] restart infosvr' 40 | shell: cd /data/PokerGo/infosvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'infosvr_restart' 43 | 44 | - name: '[infosvr] check infosvr' 45 | shell: cd /data/PokerGo/infosvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'infosvr_check' 48 | 49 | - name: '[infosvr] delLog infosvr' 50 | shell: cd /data/PokerGo/logs/infosvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'infosvr_delLog' -------------------------------------------------------------------------------- /deploy/roles/mailsvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[mailsvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/mailsvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/mailsvr 13 | tags: 'mailsvr_init' 14 | - name: '[mailsvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/mailsvr/server.sh 18 | mode: '0755' 19 | tags: "mailsvr_init" 20 | 21 | - name: '[mailsvr] Copy bin' 22 | copy: 23 | src: ../build/mailsvr 24 | dest: /data/PokerGo/mailsvr/mailsvr 25 | mode: '755' 26 | backup: yes 27 | tags: "mailsvr_push" 28 | 29 | - name: '[mailsvr] start mailsvr' 30 | shell: cd /data/PokerGo/mailsvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'mailsvr_start' 33 | 34 | - name: '[mailsvr] stop mailsvr' 35 | shell: cd /data/PokerGo/mailsvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'mailsvr_stop' 38 | 39 | - name: '[mailsvr] restart mailsvr' 40 | shell: cd /data/PokerGo/mailsvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'mailsvr_restart' 43 | 44 | - name: '[mailsvr] check mailsvr' 45 | shell: cd /data/PokerGo/mailsvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'mailsvr_check' 48 | 49 | - name: '[mailsvr] delLog mailsvr' 50 | shell: cd /data/PokerGo/logs/mailsvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'mailsvr_delLog' -------------------------------------------------------------------------------- /deploy/roles/mainsvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[mainsvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/mainsvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/mainsvr 13 | tags: 'mainsvr_init' 14 | - name: '[mainsvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/mainsvr/server.sh 18 | mode: '0755' 19 | tags: "mainsvr_init" 20 | 21 | - name: '[mainsvr] Copy bin' 22 | copy: 23 | src: ../build/mainsvr 24 | dest: /data/PokerGo/mainsvr/mainsvr 25 | mode: '0755' 26 | backup: yes 27 | tags: "mainsvr_push" 28 | 29 | - name: '[mainsvr] start mainsvr' 30 | shell: cd /data/PokerGo/mainsvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'mainsvr_start' 33 | 34 | - name: '[mainsvr] stop mainsvr' 35 | shell: cd /data/PokerGo/mainsvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'mainsvr_stop' 38 | 39 | - name: '[mainsvr] restart mainsvr' 40 | shell: cd /data/PokerGo/mainsvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'mainsvr_restart' 43 | 44 | - name: '[mainsvr] check mainsvr' 45 | shell: cd /data/PokerGo/mainsvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'mainsvr_check' 48 | 49 | - name: '[mainsvr] delLog mainsvr' 50 | shell: cd /data/PokerGo/logs/mainsvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'mainsvr_delLog' -------------------------------------------------------------------------------- /deploy/roles/mysqlsvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[mysqlsvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/mysqlsvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/mysqlsvr 13 | tags: 'mysqlsvr_init' 14 | - name: '[mysqlsvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/mysqlsvr/server.sh 18 | mode: '0755' 19 | tags: "mysqlsvr_init" 20 | 21 | - name: '[mysqlsvr] Copy bin' 22 | copy: 23 | src: ../build/mysqlsvr 24 | dest: /data/PokerGo/mysqlsvr/mysqlsvr 25 | mode: '0755' 26 | backup: yes 27 | tags: "mysqlsvr_push" 28 | 29 | - name: '[mysqlsvr] start mysqlsvr' 30 | shell: cd /data/PokerGo/mysqlsvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'mysqlsvr_start' 33 | 34 | - name: '[mysqlsvr] stop mysqlsvr' 35 | shell: cd /data/PokerGo/mysqlsvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'mysqlsvr_stop' 38 | 39 | - name: '[mysqlsvr] restart mysqlsvr' 40 | shell: cd /data/PokerGo/mysqlsvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'mysqlsvr_restart' 43 | 44 | - name: '[mysqlsvr] check mysqlsvr' 45 | shell: cd /data/PokerGo/mysqlsvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'mysqlsvr_check' 48 | 49 | - name: '[mysqlsvr] delLog mysqlsvr' 50 | shell: cd /data/PokerGo/logs/mysqlsvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'mysqlsvr_delLog' -------------------------------------------------------------------------------- /deploy/roles/roomcentersvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[roomcentersvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/roomcentersvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/roomcentersvr 13 | tags: 'roomcentersvr_init' 14 | - name: '[roomcentersvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/roomcentersvr/server.sh 18 | mode: '0755' 19 | tags: "roomcentersvr_init" 20 | 21 | - name: '[roomcentersvr] Copy bin' 22 | copy: 23 | src: ../build/roomcentersvr 24 | dest: /data/PokerGo/roomcentersvr/roomcentersvr 25 | mode: '755' 26 | backup: yes 27 | tags: "roomcentersvr_push" 28 | 29 | - name: '[roomcentersvr] start roomcentersvr' 30 | shell: cd /data/PokerGo/roomcentersvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'roomcentersvr_start' 33 | 34 | - name: '[roomcentersvr] stop roomcentersvr' 35 | shell: cd /data/PokerGo/roomcentersvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'roomcentersvr_stop' 38 | 39 | - name: '[roomcentersvr] restart roomcentersvr' 40 | shell: cd /data/PokerGo/roomcentersvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'roomcentersvr_restart' 43 | 44 | - name: '[roomcentersvr] check roomcentersvr' 45 | shell: cd /data/PokerGo/roomcentersvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'roomcentersvr_check' 48 | 49 | - name: '[roomcentersvr] delLog roomcentersvr' 50 | shell: cd /data/PokerGo/logs/roomcentersvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'roomcentersvr_delLog' -------------------------------------------------------------------------------- /deploy/roles/texassvr/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: '[texassvr] Create a directory if it does not exist' 4 | file: 5 | path: '{{ item }}' 6 | state: directory 7 | mode: '0755' 8 | with_items: 9 | - /data/PokerGo/ 10 | - /data/PokerGo/texassvr/ 11 | - /data/PokerGo/logs/ 12 | - /data/PokerGo/logs/texassvr 13 | tags: 'texassvr_init' 14 | - name: '[texassvr] Copy scripts' 15 | copy: 16 | src: ./scripts/server.sh 17 | dest: /data/PokerGo/texassvr/server.sh 18 | mode: '0755' 19 | tags: "texassvr_init" 20 | 21 | - name: '[texassvr] Copy bin' 22 | copy: 23 | src: ../build/texassvr 24 | dest: /data/PokerGo/texassvr/texassvr 25 | mode: '755' 26 | backup: yes 27 | tags: "texassvr_push" 28 | 29 | - name: '[texassvr] start texassvr' 30 | shell: cd /data/PokerGo/texassvr; ./server.sh start; ./server.sh check 31 | ignore_errors: yes 32 | tags: 'texassvr_start' 33 | 34 | - name: '[texassvr] stop texassvr' 35 | shell: cd /data/PokerGo/texassvr; ./server.sh stop 36 | ignore_errors: yes 37 | tags: 'texassvr_stop' 38 | 39 | - name: '[texassvr] restart texassvr' 40 | shell: cd /data/PokerGo/texassvr; ./server.sh restart; ./server.sh check 41 | ignore_errors: yes 42 | tags: 'texassvr_restart' 43 | 44 | - name: '[texassvr] check texassvr' 45 | shell: cd /data/PokerGo/texassvr; ./server.sh check 46 | ignore_errors: yes 47 | tags: 'texassvr_check' 48 | 49 | - name: '[texassvr] delLog texassvr' 50 | shell: cd /data/PokerGo/logs/texassvr; rm ./* 51 | ignore_errors: yes 52 | tags: 'texassvr_delLog' -------------------------------------------------------------------------------- /doc/G1服务器技术架构文档.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iori372552686/GoOne/3c7221b932ccb682a21402d8ca276c95e4ca8134/doc/G1服务器技术架构文档.docx -------------------------------------------------------------------------------- /doc/setup_win.md: -------------------------------------------------------------------------------- 1 | # Install GoLang 2 | * [下载页面](https://golang.org/dl/) 3 | * [下载地址(1.13.1)](https://dl.google.com/go/go1.13.1.windows-amd64.msi) 4 | 5 | 6 | # Install RabbitMQ 7 | ## Dependency: Erlang 8 | * [下载页面](https://www.erlang.org/downloads) 9 | * [下载地址(22.1)](http://erlang.org/download/otp_win64_22.1.exe) 10 | ## RabbitMQ 11 | * [下载页面](https://www.rabbitmq.com/download.html) 12 | * [下载地址(3.8.0)](https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.0/rabbitmq-server-3.8.0.exe) 13 | ## Plugins: rabbitmq_management 14 | * 开启 15 | ``` 16 | cd ${RabbitMQ_Dir}/sbin 17 | rabbitmq-plugins.bat enable rabbitmq_management 18 | ``` 19 | * 访问地址:http://localhost:15672 20 | * 账号/密码:guest/guest 21 | 22 | 23 | # Install ZooKeeper 24 | ## Dependency: JRE 25 | * 下载安装JRE(可能需要手动设置JAVA_HOME环境变量) 26 | ## ZooKeeper 27 | * 下载 28 | * [下载页面](https://zookeeper.apache.org/releases.html) (注意是下载bin.tar.gz,而不是tar.gz) 29 | * 解压 30 | * 配置文件 31 | ``` 32 | cd ${ZOOKEEPER_HOME}/conf 33 | rename zoo_sample.cfg zoo.cfg 34 | edit zoo.cfg # change dataDir 35 | ``` 36 | * 环境变量 37 | * ZOOKEEPER_HOME = ${ZOOKEEPER_HOME} 38 | * PATH += ;%ZOOKEEPER_HOME%\bin 39 | * 运行bin/zkServer 40 | * GUI查询工具 41 | * [zkui](https://github.com/echoma/zkui) 42 | 43 | 44 | # Install Redis (Win10) 45 | * 启动WSL。在管理员权限的PowerShell中运行: 46 | ``` 47 | Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux 48 | ``` 49 | * 在Windows Store中安装Ubuntu 50 | * 登录Ubuntu,更改镜像到aliyun。参照:[aliyun mirror](https://developer.aliyun.com/mirror/ubuntu) 51 | ``` 52 | cd /etc/apt 53 | sudo cp sources.list sources.list.backup 54 | sudo vi sources.list 55 | 56 | :%s/archive.ubuntu.com/mirrors.aliyun.com/gc 57 | :%s/http:/https:/gc 58 | ``` 59 | * 安装redis-server 60 | ``` 61 | sudo apt-get update 62 | sudo apt-get upgrade 63 | sudo apt-get install redis-server 64 | sudo service redis-server start 65 | ``` -------------------------------------------------------------------------------- /env/docker.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | mysql: 3 | image: mysql:8.4.3 4 | container_name: mysql 5 | environment: 6 | MYSQL_ROOT_PASSWORD: Iori123456 7 | MYSQL_DATABASE: game 8 | ports: 9 | - "3306:3306" 10 | networks: 11 | my_bridge_network: 12 | 13 | redis: 14 | image: redis:7.4.0 15 | container_name: redis 16 | ports: 17 | - "6379:6379" 18 | environment: 19 | REDIS_PASSWORD: 123456 20 | networks: 21 | my_bridge_network: 22 | 23 | zookeeper: 24 | image: ubuntu/zookeeper 25 | container_name: zookeeper 26 | ports: 27 | - "2181:2181" 28 | environment: 29 | ZOO_MY_ID: 1 30 | ZOO_SERVERS: server.1=zookeeper:2888:3888 31 | networks: 32 | my_bridge_network: 33 | 34 | rabbitmq: 35 | image: rabbitmq:3.13.6-management-alpine 36 | container_name: rabbitmq 37 | hostname: bt-rabbitmq 38 | environment: 39 | RABBITMQ_DEFAULT_USER: guest 40 | RABBITMQ_DEFAULT_PASS: guest 41 | RABBITMQ_LOOPBACK_USERS: "none" # 允许 guest 远程访问 42 | ports: 43 | - "5672:5672" # 映射 RabbitMQ 的 AMQP 端口 44 | - "15672:15672" # 映射 RabbitMQ 的管理界面端口 45 | restart: always 46 | networks: 47 | my_bridge_network: 48 | 49 | networks: 50 | my_bridge_network: 51 | driver: bridge 52 | -------------------------------------------------------------------------------- /lib/api/cmd_handler/cmd_handler_i.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 5 | "github.com/golang/protobuf/proto" 6 | ) 7 | 8 | type CmdHandlerFunc func(c IContext, data []byte) g1_protocol.ErrorCode 9 | 10 | // Transaction 实现了这个借口,在事务运行时保存了上下文 11 | type IContext interface { 12 | Uid() uint64 13 | Zone() uint32 14 | Rid() uint64 15 | OriSrcBusId() uint32 16 | Ip() uint32 17 | Flag() uint32 18 | 19 | ParseMsg(data []byte, msg proto.Message) error 20 | 21 | CallMsgBySvrType(svrType uint32, cmd g1_protocol.CMD, req proto.Message, rsp proto.Message) error // 常规rpc call 22 | CallMsgByRouter(svrType uint32, routerId uint64, cmd g1_protocol.CMD, req proto.Message, rsp proto.Message) error // 带自定义路由的 call 23 | CallOtherMsgBySvrType(svrType uint32, routerId, uid uint64, zone uint32, cmd g1_protocol.CMD, req proto.Message, rsp proto.Message) error //附带其他玩家id的call 24 | SendMsgBack(pbMsg proto.Message) //rpc msg back 25 | SendMsgByServerType(svrType uint32, cmd g1_protocol.CMD, req proto.Message) error // 常规rpc send 26 | SendMsgByRouter(svrType uint32, routerId uint64, cmd g1_protocol.CMD, req proto.Message) error //带自定义路由的 send 27 | //SendPbMsgByBusId(busId uint32, cmd uint32, req proto.Message) error 28 | 29 | Errorf(format string, args ...interface{}) 30 | Warningf(format string, args ...interface{}) 31 | Infof(format string, args ...interface{}) 32 | Debugf(format string, args ...interface{}) 33 | } 34 | -------------------------------------------------------------------------------- /lib/api/error_capture/error_capture_test.go: -------------------------------------------------------------------------------- 1 | package error_capture 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/getsentry/sentry-go" 8 | ) 9 | 10 | func Test_ErrorCapture(t *testing.T) { 11 | str := "测试" 12 | userId := "0526_90001" 13 | userName := "Name_0526_90001" 14 | id := 052601 15 | errMsg := "cs" 16 | 17 | // InitBugsnag(BUGSNAG_VERSION_READY, "game_ready", "3") 18 | // Error(userId, userName, str, id, errMsg) 19 | 20 | InitSentry( 21 | "https://1fb15babfd3b4705b371b2819db269c7:9aaef6b1d5bd4cf5ac02e45b461c8184@sentry.io/1859718", 22 | 23 | "test_version_0526", 24 | "test_0526", 25 | "test_release_0526", 26 | userId, 27 | ) 28 | 29 | CaptureErrorToSentry(sentry.LevelError, userId, userName, str, id, errMsg) 30 | time.Sleep(5 * time.Second) 31 | } 32 | -------------------------------------------------------------------------------- /lib/api/error_capture/sentry.go: -------------------------------------------------------------------------------- 1 | package error_capture 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | 8 | "github.com/getsentry/sentry-go" 9 | ) 10 | 11 | type sentryConfig struct { 12 | Dsn string 13 | Environment string 14 | ServerName string 15 | Release string 16 | PlayId string 17 | } 18 | 19 | var sentryCnf = sentryConfig{} 20 | 21 | func InitSentry(dsn, serviceVersion, serviceName, release, playId string) error { 22 | sentryCnf.Dsn = dsn 23 | sentryCnf.Environment = serviceVersion 24 | sentryCnf.ServerName = serviceName 25 | sentryCnf.Release = release 26 | sentryCnf.PlayId = playId 27 | err := sentry.Init(sentry.ClientOptions{ 28 | Dsn: dsn, 29 | Environment: serviceVersion, 30 | ServerName: serviceName, 31 | Release: release, 32 | }) 33 | sentry.Flush(time.Second * 5) 34 | return err 35 | } 36 | 37 | func CaptureErrorToSentry(level sentry.Level, userId, userName, errTile string, v ...interface{}) { 38 | buf := make([]byte, 4096) 39 | buf = buf[:runtime.Stack(buf, false)] 40 | stack := fmt.Sprintf("%s", buf) 41 | errMsg := fmt.Sprintf(errTile, v...) 42 | 43 | event := sentry.NewEvent() 44 | event.Level = level 45 | event.Message = errTile 46 | event.Logger = errMsg 47 | event.Timestamp = time.Now() 48 | event.User.ID = userId 49 | event.User.Username = userName 50 | if event.User.ID == "" { 51 | event.User.ID = sentryCnf.PlayId 52 | event.User.Username = sentryCnf.ServerName 53 | } 54 | 55 | event.Breadcrumbs = []*sentry.Breadcrumb{ 56 | &sentry.Breadcrumb{ 57 | Level: level, 58 | Message: fmt.Sprintf("\n%s\n%s", errMsg, stack), 59 | Timestamp: time.Now(), 60 | }, 61 | } 62 | 63 | sentry.CaptureEvent(event) 64 | } 65 | -------------------------------------------------------------------------------- /lib/api/http_sign/config.go: -------------------------------------------------------------------------------- 1 | package http_sign 2 | 3 | // HTTPSignApi config struct 4 | 5 | type Config struct { 6 | IndexName string `json:"IndexName" yaml:"IndexName"` 7 | PrivateKey string `json:"PrivateKey" yaml:"PrivateKey"` 8 | SignName string `json:"SignName" yaml:"SignName"` 9 | ExpiredTime int `json:"ExpiredTime" yaml:"ExpiredTime"` 10 | TimestampName string `json:"TimestampName" yaml:"TimestampName"` 11 | SignType string `json:"SignType" yaml:"SignType"` 12 | RequestIDName string `json:"RequestIDName" yaml:"RequestIDName"` 13 | VersionType string `json:"VersionType" yaml:"VersionType"` 14 | } 15 | -------------------------------------------------------------------------------- /lib/api/logger/plug/cmd_blacklist.go: -------------------------------------------------------------------------------- 1 | package plug 2 | 3 | // CmdBlacklist 管理int32类型命令的黑名单,需要注意并发安全,无锁 4 | type CmdBlacklist struct { 5 | commands map[uint32]bool 6 | } 7 | 8 | func NewCmdBlacklist() *CmdBlacklist { 9 | return &CmdBlacklist{ 10 | commands: make(map[uint32]bool), 11 | } 12 | } 13 | 14 | func (c *CmdBlacklist) Register(cmd uint32) { 15 | c.commands[cmd] = true 16 | } 17 | 18 | func (c *CmdBlacklist) IsBlocked(cmd uint32) bool { 19 | return c.commands[cmd] 20 | } 21 | 22 | func (c *CmdBlacklist) Unregister(cmd uint32) { 23 | delete(c.commands, cmd) 24 | } 25 | 26 | // GetAll 获取所有黑名单命令 27 | func (c *CmdBlacklist) GetAll() []uint32 { 28 | list := make([]uint32, 0, len(c.commands)) 29 | for cmd := range c.commands { 30 | list = append(list, cmd) 31 | } 32 | return list 33 | } 34 | -------------------------------------------------------------------------------- /lib/api/logger/plug/notify.go: -------------------------------------------------------------------------------- 1 | package plug 2 | 3 | import ( 4 | "bytes" 5 | "github.com/bytedance/sonic/encoder" 6 | "net/http" 7 | ) 8 | 9 | const DingDingFatalHookAddr = "https://oapi.dingtalk.com/robot/send?access_token=d92402471615f696534f8eb2ca3d8f7d79e1b5393e5d091df777a9ac1cf213e5" 10 | 11 | func UploadFatalToDingHook(msgbody string) { 12 | body := map[string]interface{}{ 13 | "msgtype": "markdown", 14 | "markdown": map[string]string{ 15 | "title": "logger", 16 | "text": msgbody, 17 | }, 18 | } 19 | 20 | var data = bytes.NewBuffer(nil) 21 | encoder.NewStreamEncoder(data).Encode(body) 22 | client := http.Client{} 23 | client.Post(DingDingFatalHookAddr, "application/json", data) 24 | } 25 | -------------------------------------------------------------------------------- /lib/api/logger/zap/logging.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2020 Alibaba Group Holding Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package zap 18 | 19 | func Fatal(args ...interface{}) { 20 | GetLogger().Fatal(args...) 21 | } 22 | 23 | func Fatalf(fmt string, args ...interface{}) { 24 | GetLogger().Fatalf(fmt, args...) 25 | } 26 | 27 | // Info is info level 28 | func Info(args ...interface{}) { 29 | GetLogger().Info(args...) 30 | } 31 | 32 | // Warn is warning level 33 | func Warn(args ...interface{}) { 34 | GetLogger().Warn(args...) 35 | } 36 | 37 | // Error is error level 38 | func Error(args ...interface{}) { 39 | GetLogger().Error(args...) 40 | } 41 | 42 | // Debug is debug level 43 | func Debug(args ...interface{}) { 44 | GetLogger().Debug(args...) 45 | } 46 | 47 | // Infof is format info level 48 | func Infof(fmt string, args ...interface{}) { 49 | GetLogger().Infof(fmt, args...) 50 | } 51 | 52 | // Warnf is format warning level 53 | func Warnf(fmt string, args ...interface{}) { 54 | GetLogger().Warnf(fmt, args...) 55 | } 56 | 57 | // Errorf is format error level 58 | func Errorf(fmt string, args ...interface{}) { 59 | GetLogger().Errorf(fmt, args...) 60 | } 61 | 62 | // Debugf is format debug level 63 | func Debugf(fmt string, args ...interface{}) { 64 | GetLogger().Debugf(fmt, args...) 65 | } 66 | 67 | func Sync() { 68 | GetLogger().Sync() 69 | } 70 | -------------------------------------------------------------------------------- /lib/api/net_conf/nacos_config.go: -------------------------------------------------------------------------------- 1 | package net_conf 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/nacos-group/nacos-sdk-go/v2/clients" 6 | "github.com/nacos-group/nacos-sdk-go/v2/clients/config_client" 7 | "github.com/nacos-group/nacos-sdk-go/v2/common/constant" 8 | "github.com/nacos-group/nacos-sdk-go/v2/vo" 9 | ) 10 | 11 | // nacos client config struct 12 | type NacosConf struct { 13 | IPAddr string `json:"ip_addr"` 14 | Port int `json:"port"` 15 | NamespaceID string `json:"namespace_id"` 16 | GroupName string `json:"group_name"` 17 | LogDir string `json:"log_dir"` 18 | CacheDir string `json:"cache_dir"` 19 | RotateTime string `json:"rotate_time"` 20 | MaxAge int `json:"max_age"` 21 | LogLevel string `json:"log_level"` 22 | UserName string `json:"user_name"` 23 | Password string `json:"password"` 24 | } 25 | 26 | func NewNacosConfigClient(conf NacosConf) config_client.IConfigClient { 27 | //server conf 28 | sc := []constant.ServerConfig{ 29 | *constant.NewServerConfig(conf.IPAddr, uint64(conf.Port)), 30 | } 31 | 32 | //client conf 33 | cc := constant.ClientConfig{ 34 | TimeoutMs: 5000, 35 | NotLoadCacheAtStart: true, 36 | NamespaceId: conf.NamespaceID, 37 | LogDir: conf.LogDir, 38 | CacheDir: conf.CacheDir, 39 | LogLevel: conf.LogLevel, 40 | Username: conf.UserName, 41 | Password: conf.Password, 42 | } 43 | 44 | // a more graceful way to create naming client 45 | client, err := clients.NewConfigClient( 46 | vo.NacosClientParam{ 47 | ClientConfig: &cc, 48 | ServerConfigs: sc, 49 | }, 50 | ) 51 | if err != nil { 52 | logger.Infof("NewConfigClient err | ", err.Error()) 53 | } 54 | 55 | return client 56 | } 57 | -------------------------------------------------------------------------------- /lib/api/rest_api/config.go: -------------------------------------------------------------------------------- 1 | package rest_api 2 | 3 | // ServiceAPI config struct 4 | type Config struct { 5 | ServiceName string `json:"service_name" yaml:"service_name"` 6 | Urls []string `json:"urls" yaml:"urls"` 7 | User string `json:"user" yaml:"user"` 8 | Pass string `json:"pass" yaml:"pass"` 9 | SignName string `json:"sign_name" yaml:"sign_name"` 10 | } 11 | 12 | /** 13 | * UrlConfig 14 | * @Description: 15 | **/ 16 | type UrlConfig struct { 17 | Urls []string 18 | UrlCount int64 19 | } 20 | -------------------------------------------------------------------------------- /lib/api/sharedstruct/cs_packet.go: -------------------------------------------------------------------------------- 1 | package sharedstruct 2 | 3 | import ( 4 | "encoding/binary" 5 | ) 6 | 7 | type CSPacket struct { 8 | Header CSPacketHeader 9 | Body []byte 10 | } 11 | 12 | // 注意这里的排列是考虑了内存对齐的情况,调整时请注意。 13 | type CSPacketHeader struct { 14 | Version uint16 15 | PassCode uint16 16 | Seq uint32 17 | 18 | Uid uint64 19 | 20 | AppVersion uint32 21 | Cmd uint32 22 | 23 | BodyLen uint32 24 | } 25 | 26 | func ByteLenOfCSPacketHeader() int { 27 | return 28 28 | } 29 | 30 | func ByteLenOfCSPacketBody(header []byte) int { 31 | return int(binary.BigEndian.Uint32(header[ByteLenOfCSPacketHeader()-4:])) 32 | } 33 | 34 | func (h *CSPacketHeader) From(b []byte) { 35 | pos := 0 36 | h.Version = binary.BigEndian.Uint16(b[pos:]) 37 | pos += 2 38 | h.PassCode = binary.BigEndian.Uint16(b[pos:]) 39 | pos += 2 40 | h.Seq = binary.BigEndian.Uint32(b[pos:]) 41 | pos += 4 42 | h.Uid = binary.BigEndian.Uint64(b[pos:]) 43 | pos += 8 44 | h.AppVersion = binary.BigEndian.Uint32(b[pos:]) 45 | pos += 4 46 | h.Cmd = binary.BigEndian.Uint32(b[pos:]) 47 | pos += 4 48 | h.BodyLen = binary.BigEndian.Uint32(b[pos:]) 49 | pos += 4 50 | } 51 | 52 | func (h *CSPacketHeader) To(b []byte) { 53 | pos := uintptr(0) 54 | binary.BigEndian.PutUint16(b[pos:], h.Version) 55 | pos += 2 56 | binary.BigEndian.PutUint16(b[pos:], h.PassCode) 57 | pos += 2 58 | binary.BigEndian.PutUint32(b[pos:], h.Seq) 59 | pos += 4 60 | binary.BigEndian.PutUint64(b[pos:], h.Uid) 61 | pos += 8 62 | binary.BigEndian.PutUint32(b[pos:], h.AppVersion) 63 | pos += 4 64 | binary.BigEndian.PutUint32(b[pos:], h.Cmd) 65 | pos += 4 66 | binary.BigEndian.PutUint32(b[pos:], h.BodyLen) 67 | pos += 4 68 | } 69 | 70 | func (h *CSPacketHeader) ToBytes() []byte { 71 | bytes := make([]byte, ByteLenOfCSPacketHeader()) 72 | h.To(bytes) 73 | return bytes 74 | } 75 | 76 | func (h *CSPacketHeader) Size() int { 77 | return ByteLenOfCSPacketHeader() 78 | } 79 | -------------------------------------------------------------------------------- /lib/api/sharedstruct/packet_test.go: -------------------------------------------------------------------------------- 1 | package sharedstruct 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "unsafe" 7 | ) 8 | 9 | func TestCap(t *testing.T) { 10 | fmt.Println(unsafe.Sizeof(SSPacketHeader{})) 11 | } 12 | -------------------------------------------------------------------------------- /lib/api/uerror/uerror.go: -------------------------------------------------------------------------------- 1 | package uerror 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | type UError struct { 9 | file string // 文件名 10 | line int // 文件行号 11 | fname string // 函数名 12 | code int32 // 错误码 13 | msg string // 错误 14 | } 15 | 16 | func (d *UError) Code() int32 { 17 | return d.code 18 | } 19 | 20 | func (d *UError) Msg() string { 21 | return d.msg 22 | } 23 | 24 | func (d *UError) Error() string { 25 | return fmt.Sprintf("%s:%d\n%s\t%d: %s", d.file, d.line, d.fname, d.code, d.msg) 26 | } 27 | 28 | func New(skip int, code int32, format string, msgs ...interface{}) *UError { 29 | // 获取调用堆栈 30 | pc, file, line, _ := runtime.Caller(skip) 31 | funcName := runtime.FuncForPC(pc).Name() 32 | // 返回错误 33 | return &UError{ 34 | file: file, 35 | line: line, 36 | fname: funcName, 37 | code: code, 38 | msg: fmt.Sprintf(format, msgs...), 39 | } 40 | } 41 | 42 | func GetCodeMsg(err error) (code int32, errmsg string) { 43 | switch vv := err.(type) { 44 | case *UError: 45 | code, errmsg = vv.Code(), vv.Error() 46 | case error: 47 | code, errmsg = -1, err.Error() 48 | } 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /lib/contrib/config/apollo/json_parser.go: -------------------------------------------------------------------------------- 1 | package apollo 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/apolloconfig/agollo/v4/constant" 7 | "github.com/apolloconfig/agollo/v4/extension" 8 | ) 9 | 10 | type jsonExtParser struct{} 11 | 12 | func (j jsonExtParser) Parse(configContent interface{}) (map[string]interface{}, error) { 13 | v, ok := configContent.(string) 14 | if !ok { 15 | return nil, nil 16 | } 17 | out := make(map[string]interface{}, 4) 18 | err := json.Unmarshal([]byte(v), &out) 19 | return out, err 20 | } 21 | 22 | func init() { 23 | // add json format 24 | extension.AddFormatParser(constant.JSON, &jsonExtParser{}) 25 | } 26 | -------------------------------------------------------------------------------- /lib/contrib/config/consul/README.md: -------------------------------------------------------------------------------- 1 | # Consul Config 2 | 3 | ```go 4 | import ( 5 | "github.com/go-kratos/kratos/contrib/config/consul/v2" 6 | "github.com/hashicorp/consul/api" 7 | ) 8 | func main() { 9 | 10 | consulClient, err := api.NewClient(&api.Config{ 11 | Address: "127.0.0.1:8500", 12 | }) 13 | if err != nil { 14 | panic(err) 15 | } 16 | cs, err := consul.New(consulClient, consul.WithPath("app/cart/configs/")) 17 | //consul中需要标注文件后缀,kratos读取配置需要适配文件后缀 18 | //The file suffix needs to be marked, and kratos needs to adapt the file suffix to read the configuration. 19 | if err != nil { 20 | panic(err) 21 | } 22 | c := config.New(config.WithSource(cs)) 23 | } 24 | ``` -------------------------------------------------------------------------------- /lib/contrib/config/consul/watcher.go: -------------------------------------------------------------------------------- 1 | package consul 2 | 3 | import ( 4 | "github.com/go-kratos/kratos/v2/config" 5 | "github.com/hashicorp/consul/api" 6 | "github.com/hashicorp/consul/api/watch" 7 | ) 8 | 9 | type watcher struct { 10 | source *source 11 | ch chan interface{} 12 | closeChan chan struct{} 13 | wp *watch.Plan 14 | } 15 | 16 | func (w *watcher) handle(idx uint64, data interface{}) { 17 | if data == nil { 18 | return 19 | } 20 | 21 | _, ok := data.(api.KVPairs) 22 | if !ok { 23 | return 24 | } 25 | 26 | w.ch <- struct{}{} 27 | } 28 | 29 | func newWatcher(s *source) (*watcher, error) { 30 | w := &watcher{ 31 | source: s, 32 | ch: make(chan interface{}), 33 | closeChan: make(chan struct{}), 34 | } 35 | 36 | wp, err := watch.Parse(map[string]interface{}{"type": "keyprefix", "prefix": s.options.path}) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | wp.Handler = w.handle 42 | w.wp = wp 43 | 44 | // wp.Run is a blocking call and will prevent newWatcher from returning 45 | go func() { 46 | err := wp.RunWithClientAndHclog(s.client, nil) 47 | if err != nil { 48 | panic(err) 49 | } 50 | }() 51 | 52 | return w, nil 53 | } 54 | 55 | func (w *watcher) Next() ([]*config.KeyValue, error) { 56 | select { 57 | case _, ok := <-w.ch: 58 | if !ok { 59 | return nil, nil 60 | } 61 | return w.source.Load() 62 | case <-w.closeChan: 63 | return nil, nil 64 | } 65 | } 66 | 67 | func (w *watcher) Stop() error { 68 | w.wp.Stop() 69 | close(w.closeChan) 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /lib/contrib/config/etcd/README.md: -------------------------------------------------------------------------------- 1 | # Etcd Config 2 | 3 | ```go 4 | import ( 5 | "zap" 6 | 7 | cfg "github.com/go-kratos/kratos/contrib/config/etcd/v2" 8 | "github.com/go-kratos/kratos/v2/config" 9 | clientv3 "go.etcd.io/etcd/client/v3" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | // create a etcd client 14 | client, err := clientv3.New(clientv3.Config{ 15 | Endpoints: []string{"127.0.0.1:2379"}, 16 | DialTimeout: time.Second, 17 | DialOptions: []grpc.DialOption{grpc.WithBlock()}, 18 | }) 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | 23 | // configure the source, "path" is required 24 | source, err := cfg.New(client, cfg.WithPath("/app-config"), cfg.WithPrefix(true)) 25 | if err != nil { 26 | log.Fatalln(err) 27 | } 28 | 29 | // create a config instance with source 30 | c := config.New(config.WithSource(source)) 31 | defer c.Close() 32 | 33 | // acquire config value 34 | foo, err := c.Value("/app-config").String() 35 | if err != nil { 36 | log.Println(err) 37 | } 38 | println(foo) 39 | 40 | ``` 41 | 42 | -------------------------------------------------------------------------------- /lib/contrib/config/etcd/watcher.go: -------------------------------------------------------------------------------- 1 | package etcd 2 | 3 | import ( 4 | "github.com/go-kratos/kratos/v2/config" 5 | clientv3 "go.etcd.io/etcd/client/v3" 6 | ) 7 | 8 | type watcher struct { 9 | source *source 10 | ch clientv3.WatchChan 11 | closeChan chan struct{} 12 | } 13 | 14 | func newWatcher(s *source) *watcher { 15 | w := &watcher{ 16 | source: s, 17 | closeChan: make(chan struct{}), 18 | } 19 | 20 | var opts []clientv3.OpOption 21 | if s.options.prefix { 22 | opts = append(opts, clientv3.WithPrefix()) 23 | } 24 | w.ch = s.client.Watch(s.options.ctx, s.options.path, opts...) 25 | 26 | return w 27 | } 28 | 29 | func (s *watcher) Next() ([]*config.KeyValue, error) { 30 | select { 31 | case _, ok := <-s.ch: 32 | if !ok { 33 | return nil, nil 34 | } 35 | return s.source.Load() 36 | case <-s.closeChan: 37 | return nil, nil 38 | } 39 | } 40 | 41 | func (s *watcher) Stop() error { 42 | close(s.closeChan) 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /lib/contrib/config/kubernetes/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Config 2 | 3 | ### Usage in the Kubernates Cluster 4 | It is required to 5 | > serviceaccount should be set to the actual account of your environment, the default account will be `namespace::default` if the `spec.serviceAccount` is unset. 6 | execute this command: 7 | ``` 8 | kubectl create clusterrolebinding go-kratos:kube --clusterrole=view --serviceaccount=mesh:default 9 | ``` 10 | or use `kubect apply -f bind-role.yaml` 11 | ```yaml 12 | apiVersion: rbac.authorization.k8s.io/v1 13 | kind: ClusterRoleBinding 14 | metadata: 15 | name: go-kratos:kube 16 | roleRef: 17 | apiGroup: rbac.authorization.k8s.io 18 | kind: ClusterRole 19 | name: view 20 | subjects: 21 | - kind: ServiceAccount 22 | name: default 23 | namespace: mesh 24 | ``` 25 | 26 | ### Usage outside the Kubernates Cluster 27 | Set the path `~/.kube/config` to KubeConfig 28 | ```go 29 | config.NewSource(SourceOption{ 30 | Namespace: "mesh", 31 | LabelSelector: "", 32 | KubeConfig: filepath.Join(homedir.HomeDir(), ".kube", "config"), 33 | }) 34 | ``` -------------------------------------------------------------------------------- /lib/contrib/config/kubernetes/config_test.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | import ( 4 | "log" 5 | "path/filepath" 6 | "testing" 7 | 8 | "github.com/go-kratos/kratos/v2/config" 9 | "k8s.io/client-go/util/homedir" 10 | ) 11 | 12 | func TestSource(t *testing.T) { 13 | home := homedir.HomeDir() 14 | s := NewSource( 15 | Namespace("mesh"), 16 | LabelSelector(""), 17 | KubeConfig(filepath.Join(home, ".kube", "config")), 18 | ) 19 | kvs, err := s.Load() 20 | if err != nil { 21 | t.Error(err) 22 | } 23 | for _, v := range kvs { 24 | t.Log(v) 25 | } 26 | } 27 | 28 | func ExampleNewSource() { 29 | conf := config.New( 30 | config.WithSource( 31 | NewSource( 32 | Namespace("mesh"), 33 | LabelSelector("app=test"), 34 | KubeConfig(filepath.Join(homedir.HomeDir(), ".kube", "config")), 35 | ), 36 | ), 37 | ) 38 | err := conf.Load() 39 | if err != nil { 40 | log.Panic(err) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/contrib/config/kubernetes/watcher.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/go-kratos/kratos/v2/config" 8 | v1 "k8s.io/api/core/v1" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | "k8s.io/apimachinery/pkg/watch" 11 | ) 12 | 13 | type watcher struct { 14 | k *kube 15 | watcher watch.Interface 16 | } 17 | 18 | func newWatcher(k *kube) (config.Watcher, error) { 19 | w, err := k.client.CoreV1().ConfigMaps(k.opts.Namespace).Watch(context.Background(), metav1.ListOptions{ 20 | LabelSelector: k.opts.LabelSelector, 21 | FieldSelector: k.opts.FieldSelector, 22 | }) 23 | if err != nil { 24 | return nil, err 25 | } 26 | return &watcher{ 27 | k: k, 28 | watcher: w, 29 | }, nil 30 | } 31 | 32 | func (w *watcher) Next() ([]*config.KeyValue, error) { 33 | ResultChan: 34 | ch := <-w.watcher.ResultChan() 35 | if ch.Object == nil { 36 | // 重新获取watcher 37 | k8sWatcher, err := w.k.client.CoreV1().ConfigMaps(w.k.opts.Namespace).Watch(context.Background(), metav1.ListOptions{ 38 | LabelSelector: w.k.opts.LabelSelector, 39 | FieldSelector: w.k.opts.FieldSelector, 40 | }) 41 | if err != nil { 42 | return nil, err 43 | } 44 | w.watcher = k8sWatcher 45 | goto ResultChan 46 | } 47 | cm, ok := ch.Object.(*v1.ConfigMap) 48 | if !ok { 49 | return nil, fmt.Errorf("kubernetes Object not ConfigMap") 50 | } 51 | if ch.Type == "DELETED" { 52 | return nil, fmt.Errorf("kubernetes configmap delete %s", cm.Name) 53 | } 54 | return w.k.configMap(*cm), nil 55 | } 56 | 57 | func (w *watcher) Stop() error { 58 | w.watcher.Stop() 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /lib/contrib/config/kubernetes/watcher_test.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | import ( 4 | "context" 5 | "path/filepath" 6 | "testing" 7 | "time" 8 | 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | "k8s.io/client-go/kubernetes" 11 | "k8s.io/client-go/tools/clientcmd" 12 | "k8s.io/client-go/util/homedir" 13 | ) 14 | 15 | func TestKube(t *testing.T) { 16 | home := homedir.HomeDir() 17 | config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(home, ".kube", "config")) 18 | if err != nil { 19 | t.Error(err) 20 | } 21 | client, err := kubernetes.NewForConfig(config) 22 | if err != nil { 23 | t.Error(err) 24 | } 25 | cmWatcher, err := client.CoreV1().ConfigMaps("mesh").Watch(context.Background(), metav1.ListOptions{ 26 | LabelSelector: "app=test", 27 | // FieldSelector: "", 28 | }) 29 | if err != nil { 30 | t.Error(err) 31 | } 32 | go func() { 33 | time.Sleep(5 * time.Second) 34 | cmWatcher.Stop() 35 | }() 36 | for c := range cmWatcher.ResultChan() { 37 | if c.Object == nil { 38 | return 39 | } 40 | t.Log(c.Type, c.Object) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/contrib/protoc/protoc-30.1-linux-x86_64/bin/protoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iori372552686/GoOne/3c7221b932ccb682a21402d8ca276c95e4ca8134/lib/contrib/protoc/protoc-30.1-linux-x86_64/bin/protoc -------------------------------------------------------------------------------- /lib/contrib/protoc/protoc-30.1-linux-x86_64/readme.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | https://developers.google.com/protocol-buffers/ 4 | This package contains a precompiled binary version of the protocol buffer 5 | compiler (protoc). This binary is intended for users who want to use Protocol 6 | Buffers in languages other than C++ but do not want to compile protoc 7 | themselves. To install, simply place this binary somewhere in your PATH. 8 | If you intend to use the included well known types then don't forget to 9 | copy the contents of the 'include' directory somewhere as well, for example 10 | into '/usr/local/include/'. 11 | Please refer to our official github site for more installation instructions: 12 | https://github.com/protocolbuffers/protobuf 13 | -------------------------------------------------------------------------------- /lib/contrib/protoc/protoc-30.1-osx-aarch_64/bin/protoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iori372552686/GoOne/3c7221b932ccb682a21402d8ca276c95e4ca8134/lib/contrib/protoc/protoc-30.1-osx-aarch_64/bin/protoc -------------------------------------------------------------------------------- /lib/contrib/protoc/protoc-30.1-osx-aarch_64/readme.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | https://developers.google.com/protocol-buffers/ 4 | This package contains a precompiled binary version of the protocol buffer 5 | compiler (protoc). This binary is intended for users who want to use Protocol 6 | Buffers in languages other than C++ but do not want to compile protoc 7 | themselves. To install, simply place this binary somewhere in your PATH. 8 | If you intend to use the included well known types then don't forget to 9 | copy the contents of the 'include' directory somewhere as well, for example 10 | into '/usr/local/include/'. 11 | Please refer to our official github site for more installation instructions: 12 | https://github.com/protocolbuffers/protobuf 13 | -------------------------------------------------------------------------------- /lib/contrib/protoc/protoc-30.1-win64/readme.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | https://developers.google.com/protocol-buffers/ 4 | This package contains a precompiled binary version of the protocol buffer 5 | compiler (protoc). This binary is intended for users who want to use Protocol 6 | Buffers in languages other than C++ but do not want to compile protoc 7 | themselves. To install, simply place this binary somewhere in your PATH. 8 | If you intend to use the included well known types then don't forget to 9 | copy the contents of the 'include' directory somewhere as well, for example 10 | into '/usr/local/include/'. 11 | Please refer to our official github site for more installation instructions: 12 | https://github.com/protocolbuffers/protobuf 13 | -------------------------------------------------------------------------------- /lib/contrib/registry/consul/service.go: -------------------------------------------------------------------------------- 1 | package consul 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/contrib/registry" 5 | "sync" 6 | "sync/atomic" 7 | ) 8 | 9 | type serviceSet struct { 10 | serviceName string 11 | watcher map[*watcher]struct{} 12 | services *atomic.Value 13 | lock sync.RWMutex 14 | } 15 | 16 | func (s *serviceSet) broadcast(ss []*registry.ServiceInstance) { 17 | s.services.Store(ss) 18 | s.lock.RLock() 19 | defer s.lock.RUnlock() 20 | for k := range s.watcher { 21 | select { 22 | case k.event <- struct{}{}: 23 | default: 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/contrib/registry/consul/watcher.go: -------------------------------------------------------------------------------- 1 | package consul 2 | 3 | import ( 4 | "context" 5 | "github.com/Iori372552686/GoOne/lib/contrib/registry" 6 | ) 7 | 8 | type watcher struct { 9 | event chan struct{} 10 | set *serviceSet 11 | 12 | // for cancel 13 | ctx context.Context 14 | cancel context.CancelFunc 15 | } 16 | 17 | func (w *watcher) Next() (services []*registry.ServiceInstance, err error) { 18 | select { 19 | case <-w.ctx.Done(): 20 | err = w.ctx.Err() 21 | case <-w.event: 22 | } 23 | 24 | ss, ok := w.set.services.Load().([]*registry.ServiceInstance) 25 | 26 | if ok { 27 | services = append(services, ss...) 28 | } 29 | return 30 | } 31 | 32 | func (w *watcher) Stop() error { 33 | w.cancel() 34 | w.set.lock.Lock() 35 | defer w.set.lock.Unlock() 36 | delete(w.set.watcher, w) 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /lib/contrib/registry/etcd/service.go: -------------------------------------------------------------------------------- 1 | package etcd 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/Iori372552686/GoOne/lib/contrib/registry" 6 | ) 7 | 8 | func marshal(si *registry.ServiceInstance) (string, error) { 9 | data, err := json.Marshal(si) 10 | if err != nil { 11 | return "", err 12 | } 13 | return string(data), nil 14 | } 15 | 16 | func unmarshal(data []byte) (si *registry.ServiceInstance, err error) { 17 | err = json.Unmarshal(data, &si) 18 | return 19 | } 20 | -------------------------------------------------------------------------------- /lib/contrib/registry/nacos/README.md: -------------------------------------------------------------------------------- 1 | # Nacos Registry 2 | 3 | ## example 4 | ### server 5 | ```go 6 | package main 7 | 8 | import ( 9 | "log" 10 | 11 | "github.com/nacos-group/nacos-sdk-go/clients" 12 | "github.com/nacos-group/nacos-sdk-go/common/constant" 13 | "github.com/nacos-group/nacos-sdk-go/vo" 14 | 15 | "github.com/go-kratos/kratos/contrib/registry/nacos/v2" 16 | "github.com/go-kratos/kratos/v2" 17 | ) 18 | 19 | func main() { 20 | sc := []constant.ServerConfig{ 21 | *constant.NewServerConfig("127.0.0.1", 8848), 22 | } 23 | 24 | 25 | client, err := clients.NewNamingClient( 26 | vo.NacosClientParam{ 27 | ServerConfigs: sc, 28 | }, 29 | ) 30 | 31 | if err != nil { 32 | log.Panic(err) 33 | } 34 | 35 | r := nacos.New(client) 36 | 37 | // server 38 | app := kratos.New( 39 | kratos.Name("helloworld"), 40 | kratos.Registrar(r), 41 | ) 42 | if err := app.Run(); err != nil { 43 | log.Fatal(err) 44 | } 45 | } 46 | ``` 47 | ### client 48 | ```go 49 | package main 50 | 51 | import ( 52 | "context" 53 | "log" 54 | 55 | "github.com/nacos-group/nacos-sdk-go/clients" 56 | "github.com/nacos-group/nacos-sdk-go/common/constant" 57 | "github.com/nacos-group/nacos-sdk-go/vo" 58 | 59 | "github.com/go-kratos/kratos/contrib/registry/nacos/v2" 60 | "github.com/go-kratos/kratos/v2/transport/grpc" 61 | ) 62 | 63 | func main() { 64 | 65 | cc := constant.ClientConfig{ 66 | NamespaceId: "public", 67 | TimeoutMs: 5000, 68 | } 69 | 70 | client, err := clients.NewNamingClient( 71 | vo.NacosClientParam{ 72 | ClientConfig: &cc, 73 | }, 74 | ) 75 | 76 | if err != nil { 77 | log.Panic(err) 78 | } 79 | 80 | r := nacos.New(client) 81 | 82 | // client 83 | conn, err := grpc.DialInsecure( 84 | context.Background(), 85 | grpc.WithEndpoint("discovery:///helloworld"), 86 | grpc.WithDiscovery(r), 87 | ) 88 | defer conn.Close() 89 | } 90 | ``` -------------------------------------------------------------------------------- /lib/contrib/registry/registry.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import "context" 4 | 5 | // Registrar is service registrar. 6 | type Registrar interface { 7 | // Register the registration. 8 | Register(ctx context.Context, service *ServiceInstance) error 9 | // Deregister the registration. 10 | Deregister(ctx context.Context, service *ServiceInstance) error 11 | } 12 | 13 | // Discovery is service discovery. 14 | type Discovery interface { 15 | // GetService return the service instances in memory according to the service name. 16 | GetService(ctx context.Context, serviceName string) ([]*ServiceInstance, error) 17 | // Watch creates a watcher according to the service name. 18 | Watch(ctx context.Context, serviceName string) (Watcher, error) 19 | } 20 | 21 | // Watcher is service watcher. 22 | type Watcher interface { 23 | // Next returns services in the following two cases: 24 | // 1.the first time to watch and the service instance list is not empty. 25 | // 2.any service instance changes found. 26 | // if the above two conditions are not met, it will block until context deadline exceeded or canceled 27 | Next() ([]*ServiceInstance, error) 28 | // Stop close the watcher. 29 | Stop() error 30 | } 31 | 32 | // ServiceInstance is an instance of a service in a discovery system. 33 | type ServiceInstance struct { 34 | // ID is the unique instance ID as registered. 35 | ID string `json:"id"` 36 | // Name is the service name as registered. 37 | Name string `json:"name"` 38 | // Version is the version of the compiled. 39 | Version string `json:"version"` 40 | // Metadata is the kv pair metadata associated with the service instance. 41 | Metadata map[string]string `json:"metadata"` 42 | // Endpoints is endpoint addresses of the service instance. 43 | Endpoints []string `json:"endpoints"` 44 | } 45 | -------------------------------------------------------------------------------- /lib/contrib/registry/zookeeper/register_test.go: -------------------------------------------------------------------------------- 1 | package zookeeper 2 | 3 | import ( 4 | "context" 5 | "github.com/Iori372552686/GoOne/lib/contrib/registry" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestRegistry(t *testing.T) { 11 | ctx := context.Background() 12 | s := ®istry.ServiceInstance{ 13 | ID: "0", 14 | Name: "helloworld", 15 | Endpoints: []string{"http://127.0.0.1:1111"}, 16 | } 17 | 18 | r, _ := New([]string{"127.0.0.1:2181"}) 19 | 20 | w, err := r.Watch(ctx, s.Name) 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | defer func() { 25 | _ = w.Stop() 26 | }() 27 | go func() { 28 | for { 29 | res, nextErr := w.Next() 30 | if nextErr != nil { 31 | return 32 | } 33 | t.Logf("watch: %d", len(res)) 34 | for _, r := range res { 35 | t.Logf("next: %+v", r) 36 | } 37 | } 38 | }() 39 | time.Sleep(time.Second) 40 | 41 | if err = r.Register(ctx, s); err != nil { 42 | t.Fatal(err) 43 | } 44 | time.Sleep(time.Second) 45 | 46 | res, err := r.GetService(ctx, s.Name) 47 | if err != nil { 48 | t.Fatal(err) 49 | } 50 | for i, re := range res { 51 | t.Logf("first %d re:%v\n", i, re) 52 | } 53 | if len(res) != 1 && res[0].Name != s.Name { 54 | t.Errorf("not expected: %+v", res) 55 | } 56 | 57 | if err = r.Deregister(ctx, s); err != nil { 58 | t.Fatal(err) 59 | } 60 | time.Sleep(time.Second) 61 | 62 | res, err = r.GetService(ctx, s.Name) 63 | if err != nil { 64 | t.Fatal(err) 65 | } 66 | for i, re := range res { 67 | t.Logf("second %d re:%v\n", i, re) 68 | } 69 | if len(res) != 0 { 70 | t.Errorf("not expected empty") 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/contrib/registry/zookeeper/service.go: -------------------------------------------------------------------------------- 1 | package zookeeper 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/contrib/registry" 5 | "sync" 6 | "sync/atomic" 7 | ) 8 | 9 | type serviceSet struct { 10 | serviceName string 11 | watcher map[*watcher]struct{} 12 | services *atomic.Value 13 | lock sync.RWMutex 14 | } 15 | 16 | func (s *serviceSet) broadcast(ss []*registry.ServiceInstance) { 17 | s.services.Store(ss) 18 | s.lock.RLock() 19 | defer s.lock.RUnlock() 20 | for k := range s.watcher { 21 | select { 22 | case k.event <- struct{}{}: 23 | default: 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/contrib/registry/zookeeper/watcher.go: -------------------------------------------------------------------------------- 1 | package zookeeper 2 | 3 | import ( 4 | "context" 5 | "github.com/Iori372552686/GoOne/lib/contrib/registry" 6 | ) 7 | 8 | var _ registry.Watcher = &watcher{} 9 | 10 | type watcher struct { 11 | ctx context.Context 12 | cancel context.CancelFunc 13 | event chan struct{} 14 | set *serviceSet 15 | } 16 | 17 | func (w watcher) Next() (services []*registry.ServiceInstance, err error) { 18 | select { 19 | case <-w.ctx.Done(): 20 | err = w.ctx.Err() 21 | case <-w.event: 22 | } 23 | ss, ok := w.set.services.Load().([]*registry.ServiceInstance) 24 | if ok { 25 | services = append(services, ss...) 26 | } 27 | return 28 | } 29 | 30 | func (w *watcher) Stop() error { 31 | w.cancel() 32 | w.set.lock.Lock() 33 | defer w.set.lock.Unlock() 34 | delete(w.set.watcher, w) 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /lib/db/mysql/mysql_facade.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "github.com/Iori372552686/GoOne/lib/api/logger" 7 | ) 8 | 9 | type IFacde interface { 10 | Init(ip string, port int16, user, password, schema string) error 11 | Execute(statement string) error 12 | Select(q string) 13 | } 14 | 15 | type Facade struct { 16 | db *sql.DB 17 | } 18 | 19 | func (f *Facade) Init(ip string, port int16, user, password, schema string) error { 20 | var err error 21 | dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", user, password, ip, port, schema) 22 | f.db, err = sql.Open("mysql", dsn) 23 | if err != nil { 24 | logger.Errorf("Failed to open a mysql {dsn:%s} | %v", dsn, err) 25 | return err 26 | } 27 | 28 | return nil 29 | } 30 | 31 | //func (f *Facade) Execute(statement string) error { 32 | // if f.db == nil { 33 | // return misc.LogError("Execute a sql on an empty db") 34 | // } 35 | // 36 | // insert, err := f.db.Query(statement) 37 | //} 38 | -------------------------------------------------------------------------------- /lib/db/redis/cap_test.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestCap(t *testing.T) { 10 | const c = 1 * 1024 11 | 12 | b := [c]byte{} 13 | for i := 0; i < c; i++ { 14 | b[i] = byte(i % 256) 15 | } 16 | 17 | redisMgr := NewRedisMgr() 18 | err := redisMgr.AddInstance(1, "10.0.0.173", 6379, "mWtiidKGE6Bb8esnFB8", 0, false) 19 | if err != nil { 20 | t.Fatal(err) 21 | } 22 | now := time.Now() 23 | for i := 0; i < 100; i++ { 24 | err = redisMgr.SetBytes(1, fmt.Sprintf("0x%08x", i), b[:]) 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | } 29 | fmt.Println(time.Since(now)) 30 | } 31 | 32 | func TestIncBy(t *testing.T) { 33 | 34 | redisMgr := NewRedisMgr() 35 | err := redisMgr.AddInstance(1, "10.0.0.173", 6379, "mWtiidKGE6Bb8esnFB8", 0, false) 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | 40 | for i := 1; i <= 24; i++ { 41 | ret, err := redisMgr.IncrByKey(1, "IncrTest2", 2) 42 | if err != nil { 43 | t.Fatal(err) 44 | } 45 | 46 | fmt.Printf("ret =%v\n", ret) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/db/redis/config.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | // db config struct 4 | type Config struct { 5 | InstanceID int `json:"InstanceId" yaml:"InstanceId"` 6 | IP string `json:"Ip" yaml:"Ip"` 7 | Port int `json:"Port" yaml:"Port"` 8 | Password string `json:"Password" yaml:"Password"` 9 | IsCluster bool `json:"IsCluster" yaml:"IsCluster"` 10 | DbIndex int `json:"DbIndex" yaml:"DbIndex"` 11 | Description string `json:"Description" yaml:"Description"` 12 | } 13 | -------------------------------------------------------------------------------- /lib/db/ssdb/config.go: -------------------------------------------------------------------------------- 1 | package ssdb 2 | 3 | //ssdb config 4 | type Config struct { 5 | InstanceID int `json:"InstanceId"` 6 | Key string `json:"Key"` 7 | IP string `json:"Ip"` 8 | Port int `json:"Port"` 9 | User string `json:"User"` 10 | Password string `json:"Password"` 11 | Description string `json:"Description"` 12 | HealthSecond int `json:"HealthSecond"` 13 | MaxPool int `json:"MaxPool"` 14 | AutoClose bool `json:"AutoClose"` 15 | MaxWaitSize int `json:"MaxWaitSize"` 16 | } 17 | -------------------------------------------------------------------------------- /lib/db/ssdb/ssdb_engin.go: -------------------------------------------------------------------------------- 1 | // by Iori 2022/1/4 2 | package ssdb 3 | 4 | import ( 5 | _ "github.com/go-sql-driver/mysql" 6 | "github.com/seefan/gossdb/v2" 7 | "github.com/seefan/gossdb/v2/conf" 8 | "github.com/seefan/gossdb/v2/pool" 9 | ) 10 | 11 | type Ssdb struct { 12 | Engine *pool.Connectors 13 | } 14 | 15 | func NewSsdbEngine() *Ssdb { 16 | r := &Ssdb{} 17 | return r 18 | } 19 | 20 | func (self *Ssdb) AddInstance(sdc Config) (*pool.Connectors, error) { 21 | se, err := gossdb.NewPool(&conf.Config{ 22 | Host: sdc.IP, 23 | Port: sdc.Port, 24 | MaxWaitSize: sdc.MaxWaitSize, 25 | PoolSize: 5, 26 | MinPoolSize: 5, 27 | MaxPoolSize: sdc.MaxPool, 28 | AutoClose: sdc.AutoClose, 29 | Password: sdc.Password, 30 | HealthSecond: sdc.HealthSecond, 31 | }) 32 | 33 | if err != nil { 34 | return nil, err 35 | } 36 | return se, nil 37 | } 38 | -------------------------------------------------------------------------------- /lib/db/ssdb/ssdb_mgr.go: -------------------------------------------------------------------------------- 1 | package ssdb 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/common/gfunc" 5 | "github.com/Iori372552686/GoOne/lib/api/logger" 6 | "github.com/seefan/gossdb/v2/pool" 7 | ) 8 | 9 | type SsdbMgr struct { 10 | Instances map[string]*Ssdb 11 | 12 | //private 13 | lastTick int64 14 | } 15 | 16 | func NewSsdbMgr() *SsdbMgr { 17 | r := &SsdbMgr{} 18 | r.Instances = make(map[string]*Ssdb) 19 | 20 | return r 21 | } 22 | 23 | func (self *SsdbMgr) SetSsdb(key string, o *Ssdb) { 24 | self.Instances[key] = o 25 | } 26 | 27 | func (self *SsdbMgr) GetSsdb(keys ...string) *Ssdb { 28 | if len(keys) == 0 { 29 | return self.Instances["default"] 30 | } else { 31 | return self.Instances[keys[0]] 32 | } 33 | } 34 | 35 | func (self *SsdbMgr) GetEngine(keys ...string) *pool.Connectors { 36 | if len(keys) == 0 { 37 | return self.Instances["default"].Engine 38 | } else { 39 | return self.Instances[keys[0]].Engine 40 | } 41 | } 42 | 43 | func (self *SsdbMgr) InitAndRun(cfgs []Config) error { 44 | logger.Infof("SsdbMgr InsInit.. ") 45 | 46 | for _, ds := range cfgs { 47 | ssdb := NewSsdbEngine() 48 | _, err := ssdb.AddInstance(ds) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | self.SetSsdb(ds.Key, ssdb) 54 | } 55 | 56 | logger.Infof("SsdbMgr InsInit... Done !") 57 | return nil 58 | } 59 | 60 | // tick 61 | func (self *SsdbMgr) Tick(nowMs int64) { 62 | defer gfunc.CheckRecover() 63 | return 64 | } 65 | -------------------------------------------------------------------------------- /lib/db/xorm/config.go: -------------------------------------------------------------------------------- 1 | package orm 2 | 3 | // DbInfo 4 | type DbInfo struct { 5 | IP string `json:"ip" yaml:"ip"` 6 | Port int `json:"port" yaml:"port"` 7 | User string `json:"user" yaml:"user"` 8 | Password string `json:"password" yaml:"password"` 9 | DBName string `json:"db_name" yaml:"db_name"` 10 | } 11 | 12 | // xorm db config struct 13 | type Config struct { 14 | InstanceID int `json:"instance_id" yaml:"instance_id"` 15 | IndexName string `json:"index_name" yaml:"index_name"` 16 | Master *DbInfo `json:"master" yaml:"master"` //主库 17 | Slaves []*DbInfo `json:"slaves" yaml:"slaves"` //从库 18 | Description string `json:"description" yaml:"description"` 19 | MaxIdle int `json:"max_idle" yaml:"max_idle"` 20 | MaxOpen int `json:"max_open" yaml:"max_open"` 21 | ShowSQL bool `json:"show_sql" yaml:"show_sql"` 22 | InitFlag bool `json:"init_flag" yaml:"init_flag"` 23 | DriveName string `json:"drive_name" yaml:"drive_name"` 24 | } 25 | -------------------------------------------------------------------------------- /lib/db/xorm/orm_session.go: -------------------------------------------------------------------------------- 1 | package orm 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/go-xorm/xorm" 6 | ) 7 | 8 | type ORMOperation func(session *xorm.Session) error 9 | 10 | /** 11 | * @Description: xorm 事务处理 12 | * @param: func 业务函数 13 | * @return: err 14 | * @Author: Iori 15 | * @Date: 2022-11-29 18:33:00 16 | **/ 17 | func (self *OrmSql) Transaction(f ORMOperation) (err error) { 18 | //session := self.Session.Begin() 19 | session := self.Engine.NewSession() 20 | 21 | err = session.Begin() 22 | if err != nil { 23 | return 24 | } 25 | 26 | defer func() { 27 | if p := recover(); p != nil { 28 | logger.Errorf("Transaction recover rollback:%s", p) 29 | session.Rollback() 30 | panic(p) // re-throw panic after Rollback 31 | } else if err != nil { 32 | logger.Errorf("Transaction error rollback:%s", err.Error()) 33 | session.Rollback() // err is non-nil; don't change it 34 | } else { 35 | err = session.Commit() // err is nil; if Commit returns error update err 36 | } 37 | }() 38 | 39 | err = f(session) //用于defer闭包检查。 40 | return err 41 | } 42 | -------------------------------------------------------------------------------- /lib/net/gnet_server/gnet_udp.go: -------------------------------------------------------------------------------- 1 | package gnet_svr 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/panjf2000/gnet" 8 | ) 9 | 10 | const ( 11 | kReadBufSize = 64 * 1024 12 | ) 13 | 14 | type udpServer struct { 15 | *gnet.EventServer 16 | 17 | handler func(conn gnet.Conn, data []byte) 18 | } 19 | 20 | func (self *udpServer) OnInitComplete(srv gnet.Server) (action gnet.Action) { 21 | log.Printf(" Gnet UDP server is listening on %s (multi-cores: %t, loops: %d)\n", 22 | srv.Addr.String(), srv.Multicore, srv.NumEventLoop) 23 | return 24 | } 25 | 26 | func (self *udpServer) React(frame []byte, c gnet.Conn) (out []byte, action gnet.Action) { 27 | self.handler(c, frame) 28 | 29 | /* 30 | // Echo asynchronously. 31 | data := append([]byte{}, frame...) 32 | go func() { 33 | time.Sleep(time.Second) 34 | c.SendTo(data) 35 | }() 36 | return 37 | */ 38 | 39 | return 40 | } 41 | 42 | func NewUdpServer(port int, cb func(conn gnet.Conn, data []byte)) error { 43 | udp := new(udpServer) 44 | udp.handler = cb 45 | 46 | go gnet.Serve(udp, fmt.Sprintf("udp://:%d", port), gnet.WithSocketRecvBuffer(kReadBufSize), gnet.WithMulticore(true), gnet.WithReusePort(true)) 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /lib/net/kcp_server/kcp_i.go: -------------------------------------------------------------------------------- 1 | package kcp_server 2 | 3 | import ( 4 | Kcp "github.com/xtaci/kcp-go/v5" 5 | ) 6 | 7 | type IKcpSvrEventHandler interface { 8 | OnConn(*Kcp.UDPSession) // 被Listener协程调用,一个KcpSvr对应一个Listener协程 9 | OnRead(*Kcp.UDPSession, []byte) int // 被Read协程调用,每个Connection对应一个Read协调 10 | OnClose(*Kcp.UDPSession) // 被Read协程调用,每个Connection对应一个Read协调 11 | } 12 | -------------------------------------------------------------------------------- /lib/net/kcp_server/kcp_test.go: -------------------------------------------------------------------------------- 1 | package kcp_server 2 | 3 | import ( 4 | "io" 5 | "log" 6 | "testing" 7 | "time" 8 | 9 | Kcp "github.com/xtaci/kcp-go/v5" 10 | ) 11 | 12 | func Test_main(t *testing.T) { 13 | //key := pbkdf2.Key([]byte("demo pass"), []byte("demo salt"), 1024, 32, sha1.New) 14 | //block, _ := kcp.NewAESBlockCrypt(key) 15 | if listener, err := Kcp.ListenWithOptions("127.0.0.1:12345", nil, 10, 3); err == nil { 16 | // spin-up the client 17 | go client() 18 | for { 19 | s, err := listener.AcceptKCP() 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | go handleEcho(s) 24 | } 25 | } else { 26 | log.Fatal(err) 27 | } 28 | } 29 | 30 | // handleEcho send back everything it received 31 | func handleEcho(conn *Kcp.UDPSession) { 32 | buf := make([]byte, 4096) 33 | for { 34 | n, err := conn.Read(buf) 35 | if err != nil { 36 | log.Println(err) 37 | return 38 | } 39 | 40 | n, err = conn.Write(buf[:n]) 41 | if err != nil { 42 | log.Println(err) 43 | return 44 | } 45 | } 46 | } 47 | 48 | func client() { 49 | //key := pbkdf2.Key([]byte("demo pass"), []byte("demo salt"), 1024, 32, sha1.New) 50 | //block, _ := kcp.NewAESBlockCrypt(key) 51 | 52 | // wait for server to become ready 53 | time.Sleep(time.Second) 54 | 55 | // dial to the echo server 56 | if sess, err := Kcp.DialWithOptions("127.0.0.1:12345", nil, 10, 3); err == nil { 57 | for { 58 | data := time.Now().String() 59 | buf := make([]byte, len(data)) 60 | log.Println("sent:", data) 61 | if _, err := sess.Write([]byte(data)); err == nil { 62 | // read back the data 63 | if _, err := io.ReadFull(sess, buf); err == nil { 64 | log.Println("recv:", string(buf)) 65 | } else { 66 | log.Fatal(err) 67 | } 68 | } else { 69 | log.Fatal(err) 70 | } 71 | time.Sleep(time.Second) 72 | } 73 | } else { 74 | log.Fatal(err) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/net/net_mgr/net_i.go: -------------------------------------------------------------------------------- 1 | package net_mgr 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/net/kcp_server" 5 | "github.com/Iori372552686/GoOne/lib/net/tcp_server" 6 | "github.com/Iori372552686/GoOne/lib/net/ws_server" 7 | "net" 8 | "sync" 9 | 10 | Kcp "github.com/xtaci/kcp-go/v5" 11 | ) 12 | 13 | type Client struct { 14 | Uid uint64 15 | Zone uint32 16 | Conn net.Conn 17 | Ip uint32 18 | Port uint32 19 | RemoteAddr string 20 | } 21 | 22 | // 必须实现 tcpserver.ITcpPacketSvrEventHandler 23 | type ConnTcpSvr struct { 24 | tcp_server.TcpPacketSvr 25 | 26 | uidConnMap map[uint64]*Client 27 | connUidMap map[net.Conn]uint64 28 | remoteAddrConnMap map[string]net.Conn 29 | remoteAddrKickMap map[string]bool 30 | lock sync.RWMutex 31 | handler func(conn net.Conn, data []byte) 32 | } 33 | 34 | type ConnKcpSvr struct { 35 | kcp_server.KcpSvr 36 | 37 | uidConnMap map[uint64]*Kcp.UDPSession 38 | connUidMap map[*Kcp.UDPSession]uint64 39 | remoteAddrConnMap map[string]*Kcp.UDPSession 40 | remoteAddrKickMap map[string]bool 41 | lock sync.RWMutex 42 | handler func(conn *Kcp.UDPSession, data []byte) 43 | } 44 | 45 | type ConnWsTcpSvr struct { 46 | ws_server.WsTcpSvr 47 | 48 | uidConnMap map[uint64]*Client 49 | connUidMap map[net.Conn]uint64 50 | remoteAddrConnMap map[string]net.Conn 51 | remoteAddrKickMap map[string]bool 52 | lock sync.RWMutex 53 | handler func(conn net.Conn, data []byte) 54 | } 55 | 56 | func NewTcpSvr() *ConnTcpSvr { 57 | return &ConnTcpSvr{} 58 | } 59 | 60 | func NewKcpSvr() *ConnKcpSvr { 61 | return &ConnKcpSvr{} 62 | } 63 | 64 | func NewWsTcpSvr() *ConnWsTcpSvr { 65 | return &ConnWsTcpSvr{} 66 | } 67 | -------------------------------------------------------------------------------- /lib/net/tcp_server/tcp_i.go: -------------------------------------------------------------------------------- 1 | package tcp_server 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | type ITcpSvrEventHandler interface { 8 | OnConn(net.Conn) // 被Listener协程调用,一个TcpSvr对应一个Listener协程 9 | OnRead(net.Conn, []byte) int // 被Read协程调用,每个Connection对应一个Read协调 10 | OnRead2(net.Conn, []byte) int 11 | OnClose(net.Conn) // 被Read协程调用,每个Connection对应一个Read协调 12 | } 13 | 14 | type ITcpPacketSvrEventHandler interface { 15 | OnConn(net.Conn) // 被Listener协程调用,一个TcpPacketSvr对应一个Listener协程 16 | OnPacket(net.Conn, []byte) // 被Read协程调用,每个Connection对应一个Read协调 17 | OnClose(net.Conn) // 被Read协程调用,每个Connection对应一个Read协调 18 | } 19 | -------------------------------------------------------------------------------- /lib/net/ws_server/beego_ws.go: -------------------------------------------------------------------------------- 1 | package ws_server 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "net" 6 | "net/http" 7 | 8 | "github.com/gorilla/websocket" 9 | ) 10 | 11 | // WsBeegoPage is beego websocket handler 12 | func (self *WsTcpSvr) WsBeegoPageUpgrader(w http.ResponseWriter, req *http.Request) { 13 | socket, err := (&websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { 14 | logger.Infof("升级协议 | ua:%v ,referer:%v", r.Header["User-Agent"], r.Header["Referer"]) 15 | return true 16 | }}).Upgrade(w, req, nil) 17 | if err != nil { 18 | http.NotFound(w, req) 19 | return 20 | } 21 | 22 | chanWrite := make(chan []byte, 100) 23 | self.lockOfConnInfo.Lock() 24 | self.mapOfConnInfo[socket.NetConn()] = chanWrite 25 | self.lockOfConnInfo.Unlock() 26 | 27 | //opt 28 | socket.NetConn().(*net.TCPConn).SetNoDelay(true) // true 表示禁用 Nagle 29 | go self.runConnRead(socket) 30 | go self.runConnWrite(socket, chanWrite) 31 | logger.Infof("beego webSocket 建立连接:%v", socket.RemoteAddr().String()) 32 | } 33 | -------------------------------------------------------------------------------- /lib/net/ws_server/gin_ws.go: -------------------------------------------------------------------------------- 1 | package ws_server 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Iori372552686/GoOne/lib/api/logger" 6 | "github.com/gin-gonic/gin" 7 | "net" 8 | "net/http" 9 | "strconv" 10 | ) 11 | 12 | var router *gin.Engine 13 | 14 | // load router 15 | func (self *WsTcpSvr) loadRoutes() { 16 | router.GET("/ws", self.wsGinPageUpgrader) 17 | } 18 | 19 | // Run gin start the websocket server 20 | func (self *WsTcpSvr) RunGinWs(mode string, wsPort int) error { 21 | port := strconv.Itoa(wsPort) 22 | if port == "" { 23 | return fmt.Errorf("port args err!") 24 | } 25 | 26 | if mode == "debug" { 27 | gin.SetMode(gin.DebugMode) 28 | } else { 29 | gin.SetMode(gin.ReleaseMode) 30 | } 31 | 32 | router = gin.Default() 33 | self.loadRoutes() 34 | 35 | go router.Run(":" + port) 36 | logger.Infof("------ Http Gin WsServer Running by :%v ------", port) 37 | return nil 38 | } 39 | 40 | // WsPage is gin websocket handler 41 | func (self *WsTcpSvr) wsGinPageUpgrader(c *gin.Context) { 42 | socket, err := upgrader.Upgrade(c.Writer, c.Request, nil) 43 | if err != nil { 44 | http.NotFound(c.Writer, c.Request) 45 | return 46 | } 47 | 48 | chanWrite := make(chan []byte, 100) 49 | self.lockOfConnInfo.Lock() 50 | self.mapOfConnInfo[socket.NetConn()] = chanWrite 51 | self.lockOfConnInfo.Unlock() 52 | 53 | //opt 54 | socket.NetConn().(*net.TCPConn).SetNoDelay(true) // true 表示禁用 Nagle 55 | go self.runConnRead(socket) 56 | go self.runConnWrite(socket, chanWrite) 57 | logger.Infof("gin webSocket 建立连接:%v", socket.RemoteAddr().String()) 58 | } 59 | -------------------------------------------------------------------------------- /lib/net/ws_server/ws_i.go: -------------------------------------------------------------------------------- 1 | package ws_server 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | type IWsTcpSvrEventHandler interface { 8 | OnConn(net.Conn) // 被Listener协程调用,一个WsSvr对应一个Listener协程 9 | OnRead(net.Conn, []byte) int // 被Read协程调用,每个Connection对应一个Read协调 10 | OnClose(net.Conn) // 被Read协程调用,每个Connection对应一个Read协调 11 | } 12 | -------------------------------------------------------------------------------- /lib/service/application/sig.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package application 5 | 6 | import ( 7 | "os" 8 | "os/signal" 9 | "syscall" 10 | ) 11 | 12 | func SignalNotify() { 13 | signal.Notify(sig, syscall.SIGABRT, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGUSR1, syscall.SIGUSR2) 14 | } 15 | 16 | func (a *Application) checkSysSignal() { 17 | select { 18 | case s := <-sig: 19 | switch s { 20 | case syscall.SIGUSR1: 21 | //logger.Infoln("onreload") 22 | a.reload() 23 | default: 24 | //logger.Infoln("onexit") 25 | a.exit() 26 | os.Exit(0) 27 | } 28 | default: 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/service/application/sig_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package application 5 | 6 | import ( 7 | "os" 8 | "os/signal" 9 | "syscall" 10 | ) 11 | 12 | func SignalNotify() { 13 | signal.Notify(sig, syscall.SIGABRT, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) 14 | } 15 | 16 | func (a *Application) checkSysSignal() { 17 | select { 18 | case s := <-sig: 19 | switch s { 20 | default: 21 | //logger.Infoln("onexit") 22 | a.exit() 23 | os.Exit(0) 24 | } 25 | default: 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/service/async/async.go: -------------------------------------------------------------------------------- 1 | package async 2 | 3 | import ( 4 | "sync" 5 | "sync/atomic" 6 | 7 | "github.com/Iori372552686/GoOne/lib/util/safego" 8 | ) 9 | 10 | const ( 11 | STATUS_RUN = 1 12 | STATUS_STOP = 2 13 | ) 14 | 15 | type Async struct { 16 | sync.WaitGroup 17 | status int32 // actor运行状态 18 | tasks *Queue // 任务队列 19 | pushCh chan struct{} // 消耗通知 20 | exitCh chan struct{} // 退出 21 | } 22 | 23 | func NewAsync() *Async { 24 | return &Async{ 25 | status: STATUS_STOP, 26 | tasks: NewQueue(), 27 | pushCh: make(chan struct{}, 1), 28 | exitCh: make(chan struct{}, 0), 29 | } 30 | } 31 | 32 | func NewAsyncPool(size int) (rets []*Async) { 33 | for i := 0; i < size; i++ { 34 | rets = append(rets, NewAsync()) 35 | } 36 | return 37 | } 38 | 39 | // 添加任务 40 | func (d *Async) Push(task func()) { 41 | if atomic.CompareAndSwapInt32(&d.status, STATUS_RUN, STATUS_RUN) { 42 | d.tasks.Push(task) 43 | // 避免阻塞 44 | select { 45 | case d.pushCh <- struct{}{}: 46 | default: 47 | } 48 | } 49 | } 50 | 51 | // 开始actor任务协程 52 | func (d *Async) Start() { 53 | if atomic.CompareAndSwapInt32(&d.status, STATUS_RUN, STATUS_RUN) { 54 | return 55 | } 56 | atomic.StoreInt32(&d.status, STATUS_RUN) 57 | d.Add(1) 58 | go d.run() 59 | } 60 | 61 | // 停止actor任务协程 62 | func (d *Async) Stop() { 63 | if atomic.CompareAndSwapInt32(&d.status, STATUS_STOP, STATUS_STOP) { 64 | return 65 | } 66 | atomic.StoreInt32(&d.status, STATUS_STOP) 67 | // 等待停止 68 | d.exitCh <- struct{}{} 69 | d.Wait() 70 | } 71 | 72 | func (d *Async) run() { 73 | defer func() { 74 | for data := d.tasks.Pop(); data != nil; data = d.tasks.Pop() { 75 | safego.SafeFunc(data.(func())) 76 | } 77 | d.Done() 78 | }() 79 | for { 80 | select { 81 | case <-d.pushCh: 82 | for data := d.tasks.Pop(); data != nil; data = d.tasks.Pop() { 83 | safego.SafeFunc(data.(func())) 84 | } 85 | case <-d.exitCh: 86 | return 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/service/async/queue.go: -------------------------------------------------------------------------------- 1 | package async 2 | 3 | import ( 4 | "sync/atomic" 5 | "unsafe" 6 | ) 7 | 8 | type node struct { 9 | next *node 10 | value interface{} 11 | } 12 | 13 | type Queue struct { 14 | head *node 15 | tail *node 16 | count int64 17 | } 18 | 19 | func NewQueuePool(size int64) (rets []*Queue) { 20 | rets = make([]*Queue, size) 21 | for i := int64(0); i < size; i++ { 22 | rets[i] = NewQueue() 23 | } 24 | return 25 | } 26 | 27 | func NewQueue() *Queue { 28 | node := new(node) 29 | return &Queue{head: node, tail: node} 30 | } 31 | 32 | // 多协程安全 33 | func (d *Queue) Push(val interface{}) { 34 | addNode := new(node) 35 | addNode.value = val 36 | // 将新增节点插入链表 37 | prevNode := (*node)(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&d.tail)), unsafe.Pointer(addNode))) 38 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&prevNode.next)), unsafe.Pointer(addNode)) 39 | atomic.AddInt64(&d.count, 1) 40 | } 41 | 42 | // 单协程安全 43 | func (d *Queue) Pop() (ret interface{}) { 44 | if node := (*node)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.head.next)))); node != nil { 45 | atomic.AddInt64(&d.count, -1) 46 | ret = node.value 47 | d.head.next = nil 48 | d.head = node 49 | } 50 | return 51 | } 52 | 53 | func (d *Queue) GetCount() int64 { 54 | return atomic.LoadInt64(&d.count) 55 | } 56 | -------------------------------------------------------------------------------- /lib/service/bus/bus_config.go: -------------------------------------------------------------------------------- 1 | package bus 2 | 3 | // bus mq client config struct 4 | type Config struct { 5 | LookupAddrs []string `json:"lookup_addrs" yaml:"lookup_addrs"` 6 | IPAddr string `json:"ip_addr" yaml:"ip_addr"` 7 | Port int `json:"port" yaml:"port"` 8 | Topics string `json:"topics" yaml:"topics"` 9 | ChanName string `json:"chan_name" yaml:"chan_name"` 10 | Concurrency int `json:"concurrency" yaml:"concurrency"` 11 | } 12 | -------------------------------------------------------------------------------- /lib/service/bus/bus_factory.go: -------------------------------------------------------------------------------- 1 | package bus 2 | 3 | // implType : args 4 | func CreateBus(implType string, selfBusId uint32, onRecvMsg MsgHandler, args ...interface{}) IBus { 5 | switch implType { 6 | case "nsq": 7 | return NewBusImplNsqMQ(selfBusId, onRecvMsg, args[0].(Config)) 8 | 9 | case "rocketmq": 10 | //todo -- need you! 11 | return nil 12 | 13 | default: //rbmq 14 | return NewBusImplRabbitMQ(selfBusId, onRecvMsg, args[0].(string)) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/service/bus/bus_i.go: -------------------------------------------------------------------------------- 1 | package bus 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | // cb handler 10 | type MsgHandler func(srcBusID uint32, data []byte) error 11 | 12 | // 需保证协程并发安全 13 | type IBus interface { 14 | SelfBusId() uint32 15 | Send(dstBusId uint32, data1 []byte, data2 []byte) error 16 | 17 | // 默认规则: 18 | // 1. onRecvMsg由实现类的内部协程调用,且只会由一个协程调用。 19 | // 2. data的所有权,转交给onRecvMsg。 20 | // 如有例外,实现类需特殊说明。 21 | SetReceiver(onRecvMsg MsgHandler) 22 | } 23 | 24 | // -------------------------------- private -------------------------------- 25 | 26 | const ( 27 | passCode = 0xFEED 28 | ) 29 | 30 | type busPacket struct { 31 | Header busPacketHeader 32 | Body []byte 33 | } 34 | 35 | type busPacketHeader struct { 36 | version uint16 37 | passCode uint16 38 | srcBusId uint32 39 | dstBusId uint32 40 | } 41 | 42 | func byteLenOfBusPacketHeader() int { 43 | return 12 44 | } 45 | 46 | func (h *busPacketHeader) From(b []byte) { 47 | h.version = binary.BigEndian.Uint16(b[0:]) 48 | h.passCode = binary.BigEndian.Uint16(b[2:]) 49 | h.srcBusId = binary.BigEndian.Uint32(b[4:]) 50 | h.dstBusId = binary.BigEndian.Uint32(b[8:]) 51 | } 52 | 53 | func (h *busPacketHeader) To(b []byte) { 54 | binary.BigEndian.PutUint16(b[0:], h.version) 55 | binary.BigEndian.PutUint16(b[2:], h.passCode) 56 | binary.BigEndian.PutUint32(b[4:], h.srcBusId) 57 | binary.BigEndian.PutUint32(b[8:], h.dstBusId) 58 | } 59 | 60 | type outMsg struct { 61 | busId uint32 62 | topics string 63 | data []byte 64 | } 65 | 66 | func calcQueueName(busId uint32) string { 67 | return "bus_" + fmt.Sprintf("%x", busId) 68 | } 69 | 70 | func sendToMsgChan(ch chan outMsg, msg outMsg, timeout time.Duration) bool { 71 | t := time.NewTimer(timeout) 72 | defer t.Stop() 73 | select { 74 | case ch <- msg: 75 | case <-t.C: 76 | return false 77 | } 78 | 79 | return true 80 | } 81 | -------------------------------------------------------------------------------- /lib/service/bus/bus_ip.go: -------------------------------------------------------------------------------- 1 | package bus 2 | 3 | import ( 4 | "bytes" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | func IpStringToInt(ipstring string) uint32 { 10 | ipSegs := strings.Split(ipstring, ".") 11 | var ipInt uint32 = 0 12 | var pos uint = 24 13 | for _, ipSeg := range ipSegs { 14 | tempInt, _ := strconv.Atoi(ipSeg) 15 | tempInt = tempInt << pos 16 | ipInt = ipInt | uint32(tempInt) 17 | pos -= 8 18 | } 19 | return ipInt 20 | } 21 | 22 | func IpIntToString(ipInt uint32) string { 23 | ipSegs := make([]string, 4) 24 | var len int = len(ipSegs) 25 | buffer := bytes.NewBufferString("") 26 | for i := 0; i < len; i++ { 27 | tempInt := ipInt & 0xFF 28 | ipSegs[len-i-1] = strconv.Itoa(int(tempInt)) 29 | ipInt = ipInt >> 8 30 | } 31 | for i := 0; i < len; i++ { 32 | buffer.WriteString(ipSegs[i]) 33 | if i < len-1 { 34 | buffer.WriteString(".") 35 | } 36 | } 37 | return buffer.String() 38 | } 39 | 40 | func ParseBusID(ipstring string) (uint32, uint32, uint32, uint32, uint32) { 41 | ipSegs := strings.Split(ipstring, ".") 42 | if len(ipSegs) < 4 { 43 | return 0, 0, 0, 0, 0 44 | } 45 | 46 | worldID, _ := strconv.Atoi(ipSegs[0]) 47 | zoneID, _ := strconv.Atoi(ipSegs[1]) 48 | funcID, _ := strconv.Atoi(ipSegs[2]) 49 | insID, _ := strconv.Atoi(ipSegs[3]) 50 | 51 | ip := (worldID << 24) + (zoneID << 16) + (funcID << 8) + insID 52 | 53 | return uint32(ip), uint32(worldID), uint32(zoneID), uint32(funcID), uint32(insID) 54 | } 55 | -------------------------------------------------------------------------------- /lib/service/bus/bus_test.go: -------------------------------------------------------------------------------- 1 | package bus 2 | 3 | import ( 4 | "log" 5 | "testing" 6 | "time" 7 | 8 | "github.com/Iori372552686/GoOne/lib/service/bus" 9 | ) 10 | 11 | func onRecvMsg(srcBusID uint32, data []byte) error { 12 | log.Printf("srcBusID:%v, data:%v", srcBusID, data) 13 | 14 | return nil 15 | } 16 | 17 | func TestBus(t *testing.T) { 18 | impl := CreateBus("rabbitmq", bus.IpStringToInt("1.1.2.2"), onRecvMsg, "amqp://guest:guest@192.168.50.11:5672/") 19 | if impl == nil { 20 | return 21 | } 22 | 23 | impl.Send(impl.SelfBusId(), []byte("abc"), nil) 24 | 25 | for i := 0; i < 10; i++ { 26 | time.Sleep(1 * time.Second) 27 | } 28 | 29 | } 30 | 31 | func TestNsqBus(t *testing.T) { 32 | conf := Config{ 33 | []string{"db-cfg-center.miniworldplus.com:4161", "db-cfg-center.miniworldplus.com:4161"}, 34 | "db-cfg-center.miniworldplus.com", 35 | 4150, 36 | "test", 37 | "ch", 38 | 3, 39 | } 40 | 41 | impl := NewBusImplNsqMQ(1, onRecvMsg, conf) 42 | if impl == nil { 43 | return 44 | } 45 | 46 | for i := 0; i < 10; i++ { 47 | impl.SendTo("test", []byte("abc"), []byte("123")) 48 | time.Sleep(1 * time.Second) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/service/bus/nsq/README.md: -------------------------------------------------------------------------------- 1 | ##### make by Iori 2 | 3 | #nsq git地址: 4 | ``` 5 | github.com/nsqio/go-nsq 6 | ``` 7 | 8 | ## 生产者示例 9 | ``` 10 | package main 11 | 12 | import ( 13 | "github.com/nsqio/go-nsq" 14 | "log" 15 | "math/rand" 16 | "time" 17 | ) 18 | 19 | func main() { 20 | config := nsq.NewConfig() 21 | w, err := nsq.NewProducer("127.0.0.1:4150", config) 22 | 23 | if err != nil { 24 | log.Panic(err) 25 | } 26 | 27 | chars := []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 28 | 29 | for { 30 | buf := make([]byte, 4) 31 | for i := 0; i < 4; i++ { 32 | buf[i] = chars[rand.Intn(len(chars))] 33 | } 34 | log.Printf("Pub: %s", buf) 35 | err = w.Publish("test", buf) 36 | if err != nil { 37 | log.Panic(err) 38 | } 39 | time.Sleep(time.Second * 1) 40 | } 41 | 42 | w.Stop() 43 | } 44 | ``` 45 | 46 | 47 | 48 | ##消费者示例 49 | ``` 50 | package main 51 | 52 | import ( 53 | "log" 54 | "sync" 55 | 56 | "github.com/nsqio/go-nsq" 57 | ) 58 | 59 | func main() { 60 | 61 | wg := &sync.WaitGroup{} 62 | wg.Add(1000) 63 | 64 | config := nsq.NewConfig() 65 | q, _ := nsq.NewConsumer("test", "ch", config) 66 | q.AddHandler(nsq.HandlerFunc(func(message *nsq.Message) error { 67 | log.Printf("Got a message: %s", message.Body) 68 | wg.Done() 69 | return nil 70 | })) 71 | err := q.ConnectToNSQD("127.0.0.1:4150") 72 | if err != nil { 73 | log.Panic(err) 74 | } 75 | wg.Wait() 76 | 77 | } 78 | ``` -------------------------------------------------------------------------------- /lib/service/bus/nsq/cap_test.go: -------------------------------------------------------------------------------- 1 | package nsq 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "log" 6 | "math/rand" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestConsumer(t *testing.T) { 12 | _, err := NewConsumer("test", "ch1", "nacos.miniworldplus.com:4161", []string{}, 3, nil) 13 | if err != nil { 14 | logger.Errorf("init Consumer error") 15 | } 16 | _, err = NewConsumer("test", "ch1", "nacos.miniworldplus.com:4161", []string{}, 3, nil) 17 | if err != nil { 18 | logger.Errorf("init Consumer error") 19 | } 20 | select {} 21 | } 22 | 23 | func TestProducer(t *testing.T) { 24 | producer, err := NewProducer("nacos.miniworldplus.com:4150") 25 | if err != nil { 26 | log.Panic(err) 27 | } 28 | 29 | chars := []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 30 | 31 | for { 32 | buf := make([]byte, 4) 33 | for i := 0; i < 4; i++ { 34 | buf[i] = chars[rand.Intn(len(chars))] 35 | } 36 | log.Printf("Pub: %s", buf) 37 | err = producer.Publish("test", buf) 38 | if err != nil { 39 | log.Panic(err) 40 | } 41 | time.Sleep(time.Second * 1) 42 | } 43 | 44 | producer.Stop() 45 | } 46 | -------------------------------------------------------------------------------- /lib/service/bus/nsq/producer.go: -------------------------------------------------------------------------------- 1 | package nsq 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/nsqio/go-nsq" 6 | ) 7 | 8 | /* 9 | * nsqProducer 10 | * @Description: 11 | */ 12 | type nsqProducer struct { 13 | *nsq.Producer 14 | } 15 | 16 | /** 17 | * @Description: 初始化生产者 18 | * @param: addr 19 | * @return: *nsqProducer 20 | * @return: error 21 | * @Author: Iori 22 | * @Date: 2022-04-22 14:05:53 23 | **/ 24 | func NewProducer(addr string) (*nsqProducer, error) { 25 | logger.Infof(" new and init producer address: %v", addr) 26 | producer, err := nsq.NewProducer(addr, nsq.NewConfig()) 27 | if err != nil { 28 | return nil, err 29 | } 30 | return &nsqProducer{producer}, nil 31 | } 32 | 33 | /** 34 | * @Description: 发布消息 35 | * @receiver: np 36 | * @param: topic 37 | * @param: message 38 | * @return: error 39 | * @Author: Iori 40 | * @Date: 2022-04-22 14:05:45 41 | **/ 42 | func (np *nsqProducer) Public(topic, message string) error { 43 | err := np.Publish(topic, []byte(message)) 44 | if err != nil { 45 | logger.Errorf("nsq public error | %v", err) 46 | return err 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /lib/service/config/nacos_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/nacos-group/nacos-sdk-go/clients" 6 | "github.com/nacos-group/nacos-sdk-go/clients/config_client" 7 | "github.com/nacos-group/nacos-sdk-go/common/constant" 8 | "github.com/nacos-group/nacos-sdk-go/vo" 9 | ) 10 | 11 | // nacos client config struct 12 | type NacosConf struct { 13 | IPAddr string `json:"ip_addr"` 14 | Port int `json:"port"` 15 | NamespaceID string `json:"namespace_id"` 16 | GroupName string `json:"group_name"` 17 | LogDir string `json:"log_dir"` 18 | CacheDir string `json:"cache_dir"` 19 | RotateTime string `json:"rotate_time"` 20 | MaxAge int `json:"max_age"` 21 | LogLevel string `json:"log_level"` 22 | } 23 | 24 | func NewNacosConfigClient(conf NacosConf) *config_client.IConfigClient { 25 | //server config 26 | sc := []constant.ServerConfig{ 27 | *constant.NewServerConfig(conf.IPAddr, uint64(conf.Port)), 28 | } 29 | 30 | //client config 31 | cc := constant.ClientConfig{ 32 | TimeoutMs: 5000, 33 | NotLoadCacheAtStart: true, 34 | NamespaceId: conf.NamespaceID, 35 | LogDir: conf.LogDir, 36 | CacheDir: conf.CacheDir, 37 | LogLevel: conf.LogLevel, 38 | } 39 | 40 | // a more graceful way to create naming client 41 | client, err := clients.NewConfigClient( 42 | vo.NacosClientParam{ 43 | ClientConfig: &cc, 44 | ServerConfigs: sc, 45 | }, 46 | ) 47 | if err != nil { 48 | logger.Infof("NewConfigClient err | ", err.Error()) 49 | } 50 | 51 | return &client 52 | } 53 | -------------------------------------------------------------------------------- /lib/service/sensitive_words/sensitive_test.go: -------------------------------------------------------------------------------- 1 | package sensitive_words 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestCap(t *testing.T) { 10 | words := strings.Split(invalidWords,",") 11 | for _, v := range words { 12 | invalidWord[v] = nil 13 | } 14 | //Set := make(map[string]interface{}, 0) 15 | set["你妈逼的"] = nil 16 | set["你妈"] = nil 17 | set["狗日"] = nil 18 | addSensitiveToMap(set) 19 | text := "文明用语你&* 妈, 逼的你这个狗 日的,怎么这么傻啊。我也是服了,我日,这些话我都说不出口" 20 | fmt.Println(ChangeSensitiveWords(text)) 21 | text = "no sensitive" 22 | fmt.Println(ChangeSensitiveWords(text)) 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /lib/service/transaction/transaction_factory.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | func NewTransactionMgr() ITransactionMgr { 4 | return new(TransactionMgr) 5 | } -------------------------------------------------------------------------------- /lib/service/transaction/transaction_i.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/cmd_handler" 5 | "github.com/Iori372552686/GoOne/lib/api/sharedstruct" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | ) 8 | 9 | type ITransactionMgr interface { 10 | // parameters: 11 | // useUidLock: 12 | // true: 每个uid最多只会有一个在执行中的协程(一般用于内存中留有uid相关信息的svr,如mainsvr)(后面的消息进队列) 13 | // false:协程数与uid无关(一般用于无状态类的svr,如dbsvr) 14 | // maxUidPendingPacket: 15 | // 当useUidLock=true时,此值为每个uid的消息等待队列的长度。 16 | InitAndRun(maxTrans int32, useUidLock bool, maxUidPendingPacket int) 17 | 18 | RegisterCmd(cmd g1_protocol.CMD, cmdHandler cmd_handler.CmdHandlerFunc) 19 | ProcessSSPacket(packet *sharedstruct.SSPacket) 20 | } 21 | -------------------------------------------------------------------------------- /lib/util/crypto/aes/base.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import ( 4 | "bytes" 5 | ) 6 | 7 | /** 8 | * @Description: pkcs 5 Padding 9 | * @param: cipherText 10 | * @param: blockSize 11 | * @return: []byte 12 | * @Author: Iori 13 | * @Date: 2023-03-06 17:21:39 14 | **/ 15 | func pkcs5Padding(cipherText []byte, blockSize int) []byte { 16 | padding := blockSize - len(cipherText)%blockSize 17 | padText := bytes.Repeat([]byte{byte(padding)}, padding) 18 | return append(cipherText, padText...) 19 | } 20 | 21 | func pkcs5UnPadding(decrypted []byte) []byte { 22 | length := len(decrypted) 23 | unPadding := int(decrypted[length-1]) 24 | return decrypted[:(length - unPadding)] 25 | } 26 | 27 | /** 28 | * @Description: pkcs 7 Padding 使用PKCS7进行填充,IOS也是7 29 | * @param: data 30 | * @return: []byte 31 | * @Author: Iori 32 | * @Date: 2023-03-06 17:22:05 33 | **/ 34 | func pkcs7Padding(ciphertext []byte, blockSize int) []byte { 35 | padding := blockSize - len(ciphertext)%blockSize 36 | padtext := bytes.Repeat([]byte{byte(padding)}, padding) 37 | return append(ciphertext, padtext...) 38 | } 39 | 40 | func pkcs7UnPadding(origData []byte) []byte { 41 | length := len(origData) 42 | unpadding := int(origData[length-1]) 43 | return origData[:(length - unpadding)] 44 | } 45 | -------------------------------------------------------------------------------- /lib/util/crypto/aes/cbc.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | "github.com/Iori372552686/GoOne/lib/util/convert" 7 | "github.com/Iori372552686/GoOne/lib/util/crypto" 8 | ) 9 | 10 | /* 11 | * 12 | - @Description: cbc encryption 128bit 13 | - @param: encryptStr 14 | - @param: key 15 | - @param: iv 16 | - @return: string 17 | - @return: error 18 | - @Author: Iori 19 | 2023-03-06 17:02:27 20 | 21 | * 22 | */ 23 | func CbcEncrypt(encrypt, key, iv string) (string, error) { 24 | encryptBytes := convert.Str2bytes(encrypt) 25 | block, err := aes.NewCipher(convert.Str2bytes(key)) 26 | if err != nil { 27 | return "", err 28 | } 29 | 30 | encryptBytes = pkcs7Padding(encryptBytes, block.BlockSize()) 31 | blockMode := cipher.NewCBCEncrypter(block, convert.Str2bytes(iv)) 32 | encrypted := make([]byte, len(encryptBytes)) 33 | blockMode.CryptBlocks(encrypted, encryptBytes) 34 | return crypto.Base64EncodeStr(encrypted), nil 35 | } 36 | 37 | /* 38 | * 39 | - @Description: cbc decrypt 40 | - @param: decryptStr 41 | - @param: key 42 | - @param: iv 43 | - @return: string 44 | - @return: error 45 | - @Author: Iori 46 | 2023-03-06 17:04:03 47 | 48 | * 49 | */ 50 | func CbcDecrypt(decryptStr string, key, iv string) (string, error) { 51 | decryptBytes, err := crypto.Base64DecodeStr(decryptStr) 52 | if err != nil { 53 | return "", err 54 | } 55 | 56 | block, err := aes.NewCipher(convert.Str2bytes(key)) 57 | if err != nil { 58 | return "", err 59 | } 60 | 61 | blockMode := cipher.NewCBCDecrypter(block, convert.Str2bytes(iv)) 62 | decrypted := make([]byte, len(decryptBytes)) 63 | blockMode.CryptBlocks(decrypted, decryptBytes) 64 | decrypted = pkcs7UnPadding(decrypted) 65 | return convert.Bytes2str(decrypted), nil 66 | } 67 | -------------------------------------------------------------------------------- /lib/util/crypto/aes/cfb.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | "github.com/Iori372552686/GoOne/lib/util/convert" 7 | "github.com/Iori372552686/GoOne/lib/util/crypto" 8 | ) 9 | 10 | /** 11 | * @Description: cfb encryption 128bit 12 | * @param: encryptStr 13 | * @param: key 14 | * @param: iv 15 | * @return: string 16 | * @return: error 17 | * @Author: Iori 18 | * @Date: 2023-03-06 17:02:27 19 | **/ 20 | func CfbEncrypt(encrypt, key, iv string) (string, error) { 21 | encryptBytes := convert.Str2bytes(encrypt) 22 | block, err := aes.NewCipher(convert.Str2bytes(key)) 23 | if err != nil { 24 | return "", err 25 | } 26 | 27 | encryptBytes = pkcs7Padding(encryptBytes, block.BlockSize()) 28 | blockMode := cipher.NewCFBEncrypter(block, convert.Str2bytes(iv)) 29 | encrypted := make([]byte, len(encryptBytes)) 30 | blockMode.XORKeyStream(encrypted, encryptBytes) 31 | return crypto.Base64EncodeStr(encrypted), nil 32 | } 33 | 34 | /** 35 | * @Description: cfb decrypt 36 | * @param: decryptStr 37 | * @param: key 38 | * @param: iv 39 | * @return: string 40 | * @return: error 41 | * @Author: Iori 42 | * @Date: 2023-03-06 17:04:03 43 | **/ 44 | func CfbDecrypt(decryptStr string, key, iv string) (string, error) { 45 | decryptBytes, err := crypto.Base64DecodeStr(decryptStr) 46 | if err != nil { 47 | return "", err 48 | } 49 | 50 | block, err := aes.NewCipher(convert.Str2bytes(key)) 51 | if err != nil { 52 | return "", err 53 | } 54 | 55 | blockMode := cipher.NewCFBDecrypter(block, convert.Str2bytes(iv)) 56 | decrypted := make([]byte, len(decryptBytes)) 57 | blockMode.XORKeyStream(decrypted, decryptBytes) 58 | decrypted = pkcs7UnPadding(decrypted) 59 | return convert.Bytes2str(decrypted), nil 60 | } 61 | -------------------------------------------------------------------------------- /lib/util/crypto/base64.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "encoding/base64" 5 | "github.com/Iori372552686/GoOne/lib/util/convert" 6 | ) 7 | 8 | var coder = base64.StdEncoding 9 | 10 | /** 11 | * @Description: base64加密 12 | * @param: src 13 | * @return: []byte 14 | * @Author: Iori 15 | * @Date: 2022-06-07 18:41:19 16 | **/ 17 | func Base64Encode(src []byte) []byte { 18 | return []byte(coder.EncodeToString(src)) 19 | } 20 | 21 | /** 22 | * @Description: base64解密 23 | * @param: src 24 | * @return: []byte 25 | * @return: error 26 | * @Author: Iori 27 | * @Date: 2022-06-07 18:41:24 28 | **/ 29 | func Base64Decode(src []byte) ([]byte, error) { 30 | return coder.DecodeString(convert.Bytes2str(src)) 31 | } 32 | 33 | /** 34 | * @Description: base64加密 str 35 | * @param: src 36 | * @return: []byte 37 | * @Author: Iori 38 | * @Date: 2022-06-07 18:41:19 39 | **/ 40 | func Base64EncodeStr(src []byte) string { 41 | return coder.EncodeToString(src) 42 | } 43 | 44 | /** 45 | * @Description: base64解密 str 46 | * @param: src 47 | * @return: []byte 48 | * @return: error 49 | * @Author: Iori 50 | * @Date: 2022-06-07 18:41:24 51 | **/ 52 | func Base64DecodeStr(src string) ([]byte, error) { 53 | return coder.DecodeString(src) 54 | } 55 | -------------------------------------------------------------------------------- /lib/util/crypto/md5.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | "strings" 7 | ) 8 | 9 | /** 10 | * @Description: 正常md5 11 | * @param: str 12 | * @return: string 13 | * @Author: Iori 14 | **/ 15 | func Md5(data string) string { 16 | h := md5.New() 17 | h.Write([]byte(data)) 18 | return hex.EncodeToString(h.Sum(nil)) 19 | } 20 | 21 | /** 22 | * @Description: md5全小写str 23 | * @param: arg0 24 | * @return: string 25 | * @Author: Iori 26 | **/ 27 | func Md5Encode(data string) string { 28 | h := md5.New() 29 | h.Write([]byte(data)) 30 | return strings.ToLower(hex.EncodeToString(h.Sum(nil))) 31 | } 32 | 33 | /** 34 | * @Description: md5全大写str 35 | * @param: arg0 36 | * @return: string 37 | * @Author: Iori 38 | **/ 39 | func Md5EncodeV2(data string) string { 40 | h := md5.New() 41 | h.Write([]byte(data)) 42 | return strings.ToUpper(hex.EncodeToString(h.Sum(nil))) 43 | } 44 | -------------------------------------------------------------------------------- /lib/util/deps/protoc/protoc-3.11.4-linux-x86_64/bin/protoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iori372552686/GoOne/3c7221b932ccb682a21402d8ca276c95e4ca8134/lib/util/deps/protoc/protoc-3.11.4-linux-x86_64/bin/protoc -------------------------------------------------------------------------------- /lib/util/deps/protoc/protoc-3.11.4-linux-x86_64/bin/protoc-gen-go: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iori372552686/GoOne/3c7221b932ccb682a21402d8ca276c95e4ca8134/lib/util/deps/protoc/protoc-3.11.4-linux-x86_64/bin/protoc-gen-go -------------------------------------------------------------------------------- /lib/util/deps/protoc/protoc-3.11.4-linux-x86_64/readme.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | https://developers.google.com/protocol-buffers/ 4 | 5 | This package contains a precompiled binary version of the protocol buffer 6 | compiler (protoc). This binary is intended for users who want to use Protocol 7 | Buffers in languages other than C++ but do not want to compile protoc 8 | themselves. To install, simply place this binary somewhere in your PATH. 9 | 10 | If you intend to use the included well known types then don't forget to 11 | copy the contents of the 'include' directory somewhere as well, for example 12 | into '/usr/local/include/'. 13 | 14 | Please refer to our official github site for more installation instructions: 15 | https://github.com/protocolbuffers/protobuf 16 | -------------------------------------------------------------------------------- /lib/util/deps/protoc/protoc-3.11.4-osx-x86_64/bin/protoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iori372552686/GoOne/3c7221b932ccb682a21402d8ca276c95e4ca8134/lib/util/deps/protoc/protoc-3.11.4-osx-x86_64/bin/protoc -------------------------------------------------------------------------------- /lib/util/deps/protoc/protoc-3.11.4-osx-x86_64/readme.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | https://developers.google.com/protocol-buffers/ 4 | 5 | This package contains a precompiled binary version of the protocol buffer 6 | compiler (protoc). This binary is intended for users who want to use Protocol 7 | Buffers in languages other than C++ but do not want to compile protoc 8 | themselves. To install, simply place this binary somewhere in your PATH. 9 | 10 | If you intend to use the included well known types then don't forget to 11 | copy the contents of the 'include' directory somewhere as well, for example 12 | into '/usr/local/include/'. 13 | 14 | Please refer to our official github site for more installation instructions: 15 | https://github.com/protocolbuffers/protobuf 16 | -------------------------------------------------------------------------------- /lib/util/deps/protoc/protoc-3.11.4-win64/readme.txt: -------------------------------------------------------------------------------- 1 | Protocol Buffers - Google's data interchange format 2 | Copyright 2008 Google Inc. 3 | https://developers.google.com/protocol-buffers/ 4 | 5 | This package contains a precompiled binary version of the protocol buffer 6 | compiler (protoc). This binary is intended for users who want to use Protocol 7 | Buffers in languages other than C++ but do not want to compile protoc 8 | themselves. To install, simply place this binary somewhere in your PATH. 9 | 10 | If you intend to use the included well known types then don't forget to 11 | copy the contents of the 'include' directory somewhere as well, for example 12 | into '/usr/local/include/'. 13 | 14 | Please refer to our official github site for more installation instructions: 15 | https://github.com/protocolbuffers/protobuf 16 | -------------------------------------------------------------------------------- /lib/util/encoding/encoding.go: -------------------------------------------------------------------------------- 1 | package encoding 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | // Codec defines the interface Transport uses to encode and decode messages. Note 8 | // that implementations of this interface must be thread safe; a Codec's 9 | // methods can be called from concurrent goroutines. 10 | type Codec interface { 11 | // Marshal returns the wire format of v. 12 | Marshal(v interface{}) ([]byte, error) 13 | // Unmarshal parses the wire format into v. 14 | Unmarshal(data []byte, v interface{}) error 15 | // Name returns the name of the Codec implementation. The returned string 16 | // will be used as part of content type in transmission. The result must be 17 | // static; the result cannot change between calls. 18 | Name() string 19 | } 20 | 21 | var registeredCodecs = make(map[string]Codec) 22 | 23 | // RegisterCodec registers the provided Codec for use with all Transport clients and 24 | // servers. 25 | func RegisterCodec(codec Codec) { 26 | if codec == nil { 27 | panic("cannot register a nil Codec") 28 | } 29 | if codec.Name() == "" { 30 | panic("cannot register Codec with empty string result for Name()") 31 | } 32 | contentSubtype := strings.ToLower(codec.Name()) 33 | registeredCodecs[contentSubtype] = codec 34 | } 35 | 36 | // GetCodec gets a registered Codec by content-subtype, or nil if no Codec is 37 | // registered for the content-subtype. 38 | // 39 | // The content-subtype is expected to be lowercase. 40 | func GetCodec(contentSubtype string) Codec { 41 | return registeredCodecs[contentSubtype] 42 | } 43 | -------------------------------------------------------------------------------- /lib/util/encoding/json/json.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/Iori372552686/GoOne/lib/util/encoding" 6 | "reflect" 7 | 8 | "google.golang.org/protobuf/encoding/protojson" 9 | "google.golang.org/protobuf/proto" 10 | ) 11 | 12 | // Name is the name registered for the json codec. 13 | const Name = "json" 14 | 15 | var ( 16 | // MarshalOptions is a configurable JSON format marshaller. 17 | MarshalOptions = protojson.MarshalOptions{ 18 | EmitUnpopulated: true, 19 | } 20 | // UnmarshalOptions is a configurable JSON format parser. 21 | UnmarshalOptions = protojson.UnmarshalOptions{ 22 | DiscardUnknown: true, 23 | } 24 | ) 25 | 26 | func init() { 27 | encoding.RegisterCodec(codec{}) 28 | } 29 | 30 | // codec is a Codec implementation with json. 31 | type codec struct{} 32 | 33 | func (codec) Marshal(v interface{}) ([]byte, error) { 34 | switch m := v.(type) { 35 | case json.Marshaler: 36 | return m.MarshalJSON() 37 | case proto.Message: 38 | return MarshalOptions.Marshal(m) 39 | default: 40 | return json.Marshal(m) 41 | } 42 | } 43 | 44 | func (codec) Unmarshal(data []byte, v interface{}) error { 45 | switch m := v.(type) { 46 | case json.Unmarshaler: 47 | return m.UnmarshalJSON(data) 48 | case proto.Message: 49 | return UnmarshalOptions.Unmarshal(data, m) 50 | default: 51 | rv := reflect.ValueOf(v) 52 | for rv := rv; rv.Kind() == reflect.Ptr; { 53 | if rv.IsNil() { 54 | rv.Set(reflect.New(rv.Type().Elem())) 55 | } 56 | rv = rv.Elem() 57 | } 58 | if m, ok := reflect.Indirect(rv).Interface().(proto.Message); ok { 59 | return UnmarshalOptions.Unmarshal(data, m) 60 | } 61 | return json.Unmarshal(data, m) 62 | } 63 | } 64 | 65 | func (codec) Name() string { 66 | return Name 67 | } 68 | -------------------------------------------------------------------------------- /lib/util/encoding/msgp/msg_pack.go: -------------------------------------------------------------------------------- 1 | // Package msgp defines the protobuf codec. Importing this package will 2 | // register the codec. 3 | package msgp 4 | 5 | import ( 6 | "github.com/Iori372552686/GoOne/lib/util/encoding" 7 | "github.com/vmihailenco/msgpack" 8 | ) 9 | 10 | // Name is the name registered for the msgpack compressor. 11 | const Name = "msgpack" 12 | 13 | func init() { 14 | encoding.RegisterCodec(codec{}) 15 | } 16 | 17 | // codec is a Codec implementation with protobuf. It is the default codec for Transport. 18 | type codec struct{} 19 | 20 | func (codec) Marshal(v interface{}) ([]byte, error) { 21 | return msgpack.Marshal(v) 22 | } 23 | 24 | func (codec) Unmarshal(data []byte, v interface{}) error { 25 | return msgpack.Unmarshal(data, v) 26 | } 27 | 28 | func (codec) Name() string { 29 | return Name 30 | } 31 | -------------------------------------------------------------------------------- /lib/util/encoding/proto/proto.go: -------------------------------------------------------------------------------- 1 | // Package proto defines the protobuf codec. Importing this package will 2 | // register the codec. 3 | package proto 4 | 5 | import ( 6 | "github.com/Iori372552686/GoOne/lib/util/encoding" 7 | 8 | "google.golang.org/protobuf/proto" 9 | ) 10 | 11 | // Name is the name registered for the proto compressor. 12 | const Name = "proto" 13 | 14 | func init() { 15 | encoding.RegisterCodec(codec{}) 16 | } 17 | 18 | // codec is a Codec implementation with protobuf. It is the default codec for Transport. 19 | type codec struct{} 20 | 21 | func (codec) Marshal(v interface{}) ([]byte, error) { 22 | return proto.Marshal(v.(proto.Message)) 23 | } 24 | 25 | func (codec) Unmarshal(data []byte, v interface{}) error { 26 | return proto.Unmarshal(data, v.(proto.Message)) 27 | } 28 | 29 | func (codec) Name() string { 30 | return Name 31 | } 32 | -------------------------------------------------------------------------------- /lib/util/encoding/xml/xml.go: -------------------------------------------------------------------------------- 1 | package xml 2 | 3 | import ( 4 | "encoding/xml" 5 | 6 | "github.com/Iori372552686/GoOne/lib/util/encoding" 7 | ) 8 | 9 | // Name is the name registered for the xml codec. 10 | const Name = "xml" 11 | 12 | func init() { 13 | encoding.RegisterCodec(codec{}) 14 | } 15 | 16 | // codec is a Codec implementation with xml. 17 | type codec struct{} 18 | 19 | func (codec) Marshal(v interface{}) ([]byte, error) { 20 | return xml.Marshal(v) 21 | } 22 | 23 | func (codec) Unmarshal(data []byte, v interface{}) error { 24 | return xml.Unmarshal(data, v) 25 | } 26 | 27 | func (codec) Name() string { 28 | return Name 29 | } 30 | -------------------------------------------------------------------------------- /lib/util/encoding/yaml/yaml.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/util/encoding" 5 | "gopkg.in/yaml.v3" 6 | ) 7 | 8 | // Name is the name registered for the yaml codec. 9 | const Name = "yaml" 10 | 11 | func init() { 12 | encoding.RegisterCodec(codec{}) 13 | } 14 | 15 | // codec is a Codec implementation with yaml. 16 | type codec struct{} 17 | 18 | func (codec) Marshal(v interface{}) ([]byte, error) { 19 | return yaml.Marshal(v) 20 | } 21 | 22 | func (codec) Unmarshal(data []byte, v interface{}) error { 23 | return yaml.Unmarshal(data, v) 24 | } 25 | 26 | func (codec) Name() string { 27 | return Name 28 | } 29 | -------------------------------------------------------------------------------- /lib/util/generic/types.go: -------------------------------------------------------------------------------- 1 | package generic 2 | 3 | // 所有整数类型以及底层类型为整数的类型 4 | type Int interface { 5 | ~int64 | ~uint64 | ~uint32 | ~int32 | ~int | ~uint 6 | } 7 | 8 | type Iter[T any] interface { 9 | Next() bool 10 | Value() T 11 | } 12 | -------------------------------------------------------------------------------- /lib/util/idgen/idgen.go: -------------------------------------------------------------------------------- 1 | package idgen 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/util/convert" 5 | "github.com/Iori372552686/GoOne/lib/util/tos" 6 | "github.com/sony/sonyflake" 7 | "strings" 8 | "time" 9 | ) 10 | 11 | type TIDGen struct { 12 | idGen *sonyflake.Sonyflake 13 | } 14 | 15 | func NewIDGen() (idg *TIDGen, err error) { 16 | addr, err := tos.GetLocalIp() 17 | if err != nil { 18 | return 19 | } 20 | var mid uint16 = 1 21 | ss := strings.Split(addr, ".") 22 | if len(ss) > 0 { 23 | mid = uint16(convert.StrToInt(ss[len(ss)-1])) 24 | } 25 | idg = &TIDGen{ 26 | idGen: newSonyFlake(mid), 27 | } 28 | return 29 | } 30 | 31 | func (i *TIDGen) GenID() (uint64, error) { 32 | return i.idGen.NextID() 33 | } 34 | 35 | func newSonyFlake(MachineID uint16) *sonyflake.Sonyflake { 36 | return sonyflake.NewSonyflake(sonyflake.Settings{ 37 | StartTime: time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC), 38 | MachineID: func() (uint16, error) { 39 | return MachineID, nil 40 | }, 41 | CheckMachineID: nil, 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /lib/util/idgen/idgen_test.go: -------------------------------------------------------------------------------- 1 | package idgen 2 | 3 | import "testing" 4 | 5 | func TestGenID(t *testing.T) { 6 | g, err := NewIDGen() 7 | if err != nil { 8 | t.Fatal(err) 9 | } 10 | id, err := g.GenID() 11 | if err != nil { 12 | t.Fatal(err) 13 | } 14 | t.Log(id) 15 | } 16 | -------------------------------------------------------------------------------- /lib/util/marshal/cap_test.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | 8 | "github.com/vmihailenco/msgpack" 9 | ) 10 | 11 | func Test_msgpack(t *testing.T) { 12 | countryCapitalMap := make(map[string]string) 13 | out := make(map[string]string) 14 | countryCapitalMap["device_id"] = "345" 15 | countryCapitalMap["session_id"] = "123" 16 | 17 | test, err := os.ReadFile("d:/test.zap") 18 | 19 | in := countryCapitalMap 20 | res, err := msgpack.Marshal(in) 21 | if err != nil { 22 | fmt.Printf("序列化失败") 23 | } 24 | 25 | fmt.Printf("原数据byte=%v", res) 26 | fmt.Printf("test byte=%v", test) 27 | 28 | err = msgpack.Unmarshal(test, &out) 29 | if err != nil { 30 | fmt.Println("反序列化失败") 31 | } 32 | fmt.Println("反序列化数据--", out) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /lib/util/marshal/load.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "path/filepath" 8 | "strings" 9 | 10 | "gopkg.in/yaml.v3" 11 | ) 12 | 13 | /** 14 | * @Description: 根据文件名,匹配解析配置协议 15 | * @param: fileName 16 | * @param: object 17 | * @return: error 18 | * @Author: Iori 19 | * @Date: 2022-07-26 17:32:38 20 | **/ 21 | func LoadConfFile(fileName string, object interface{}) error { 22 | var err error 23 | 24 | switch filepath.Ext(strings.ToLower(fileName)) { 25 | case ".json": 26 | err = LoadJson(fileName, object) 27 | case ".yaml", ".yml": 28 | err = LoadYaml(fileName, object) 29 | default: 30 | err = LoadJson(fileName, object) 31 | } 32 | 33 | return err 34 | } 35 | 36 | /** 37 | * @Description: 加载并解析json文件 38 | * @param: filePath 39 | * @param: object 40 | * @return: error 41 | * @Author: Iori 42 | * @Date: 2022-02-15 15:11:09 43 | **/ 44 | func LoadJson(filePath string, object interface{}) error { 45 | contents, err := ioutil.ReadFile(filePath) 46 | if err != nil { 47 | return fmt.Errorf("failed to open file: %v | %w", filePath, err) 48 | } 49 | 50 | err = json.Unmarshal(contents, object) 51 | if err != nil { 52 | return fmt.Errorf("failed to unmarshal config: %v | %w", filePath, err) 53 | } 54 | 55 | return nil 56 | } 57 | 58 | /** 59 | * @Description: 加载并解析yaml文件 60 | * @param: filePath 61 | * @param: object 62 | * @return: error 63 | * @Author: Iori 64 | * @Date: 2022-02-15 15:11:42 65 | **/ 66 | func LoadYaml(filePath string, object interface{}) error { 67 | contents, err := ioutil.ReadFile(filePath) 68 | if err != nil { 69 | return fmt.Errorf("failed to open file: %v | %w", filePath, err) 70 | } 71 | 72 | err = yaml.Unmarshal(contents, object) 73 | if err != nil { 74 | return fmt.Errorf("failed to unmarshal config: %v | %w", filePath, err) 75 | } 76 | 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /lib/util/mutex/try_lock.go: -------------------------------------------------------------------------------- 1 | package mutex 2 | 3 | import ( 4 | "sync" 5 | "sync/atomic" 6 | "unsafe" 7 | ) 8 | 9 | // 复制Mutex定义的常量 10 | const ( 11 | mutexLocked = 1 << iota // 加锁标识位置 12 | mutexWoken // 唤醒标识位置 13 | mutexStarving // 锁饥饿标识位置 14 | mutexWaiterShift = iota // 标识waiter的起始bit位置 15 | ) 16 | 17 | // 扩展一个Mutex结构 18 | type Mutex struct { 19 | sync.Mutex 20 | } 21 | 22 | // 尝试获取锁 PS:在 Go 1.18 官方标准库中,已经为 Mutex/RWMutex 增加了 TryLock 方法。 23 | func (m *Mutex) TryLock() bool { 24 | // 如果能成功抢到锁 25 | if atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), 0, mutexLocked) { 26 | return true 27 | } 28 | 29 | // 如果处于唤醒、加锁或者饥饿状态,这次请求就不参与竞争了,返回false 30 | old := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 31 | if old&(mutexLocked|mutexStarving|mutexWoken) != 0 { 32 | return false 33 | } 34 | 35 | // 尝试在竞争的状态下请求锁 36 | new := old | mutexLocked 37 | return atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), old, new) 38 | } 39 | 40 | /** 41 | * @Description: 获取等待这把锁的 goroutine 的总数 42 | * @return: int 43 | * @Author: Iori 44 | * @Date: 2023-06-09 14:41:52 45 | **/ 46 | func (m *Mutex) Count() int { 47 | // 获取state字段的值 48 | v := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 49 | v = v>>mutexWaiterShift + (v & mutexLocked) 50 | return int(v) 51 | } 52 | 53 | // 锁是否被持有 54 | func (m *Mutex) IsLocked() bool { 55 | state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 56 | return state&mutexLocked == mutexLocked 57 | } 58 | 59 | // 是否有等待者被唤醒 60 | func (m *Mutex) IsWoken() bool { 61 | state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 62 | return state&mutexWoken == mutexWoken 63 | } 64 | 65 | // 锁是否处于饥饿状态 66 | func (m *Mutex) IsStarving() bool { 67 | state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 68 | return state&mutexStarving == mutexStarving 69 | } 70 | -------------------------------------------------------------------------------- /lib/util/random/bytes.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "encoding/binary" 5 | "math/rand" 6 | ) 7 | 8 | // GetBytes 最多返回1~1024 字节长度的随机bytes 9 | func GetBytes(size int) []byte { 10 | if size <= 0 || size > 1024 { 11 | return nil 12 | } 13 | buf := make([]byte, size) 14 | n := size / 8 15 | r := size % 8 16 | bs := n * 8 17 | for i := 0; i < n; i++ { 18 | rd := rand.Uint64() 19 | binary.BigEndian.PutUint64(buf[i*8:], rd) 20 | } 21 | 22 | for i := 0; i < r; i++ { 23 | buf[bs+i] = byte(rand.Uint64() % 0xff) 24 | } 25 | return buf 26 | } 27 | -------------------------------------------------------------------------------- /lib/util/random/init.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | encoding_binary "encoding/binary" 5 | "io" 6 | math_rand "math/rand" 7 | "os" 8 | "runtime" 9 | "time" 10 | ) 11 | 12 | func init() { 13 | var seed uint64 14 | if runtime.GOOS == "linux" { 15 | fp, err := os.Open("/dev/urandom") 16 | if err != nil { 17 | panic(err) 18 | } 19 | defer fp.Close() 20 | bytes := make([]byte, 8) 21 | if _, err = io.ReadFull(fp, bytes); err != nil { 22 | panic(err) 23 | } 24 | seed = encoding_binary.LittleEndian.Uint64(bytes) 25 | } else { 26 | seed = uint64(time.Now().Nanosecond()) 27 | } 28 | math_rand.Seed(int64(seed)) 29 | } 30 | -------------------------------------------------------------------------------- /lib/util/random/rand_test.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestGetString(t *testing.T) { 11 | for i := 0; i < 10; i++ { 12 | t.Log(GetString(20)) 13 | } 14 | } 15 | 16 | func TestGetBytes(t *testing.T) { 17 | for i := 0; i < 10; i++ { 18 | bts := GetBytes(20) 19 | t.Log(bts) 20 | if len(bts) != 20 { 21 | panic("not equal") 22 | } 23 | } 24 | bts := GetBytes(-1) 25 | assert.Nil(t, bts) 26 | 27 | bts = GetBytes(2048) 28 | assert.Nil(t, bts) 29 | 30 | bts = GetBytes(1024) 31 | assert.Equal(t, 1024, len(bts)) 32 | 33 | } 34 | 35 | func TestParallelRand(t *testing.T) { 36 | var wg sync.WaitGroup 37 | const workerNum = 100 38 | wg.Add(workerNum) 39 | for i := 0; i < workerNum; i++ { 40 | go func() { 41 | for j := 0; j < 100000; j++ { 42 | _ = Int() 43 | } 44 | wg.Done() 45 | }() 46 | } 47 | wg.Wait() 48 | } 49 | 50 | func TestUint(t *testing.T) { 51 | ret := Uint64() 52 | assert.True(t, ret > 0) 53 | } 54 | 55 | func TestLimit(t *testing.T) { 56 | ret := Intn(100) 57 | assert.True(t, ret < 100 && ret > 0) 58 | } 59 | -------------------------------------------------------------------------------- /lib/util/random/string.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | const ( 9 | letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 10 | letterIdxBits = 6 // 6 bits to represent a letter index 11 | letterIdxMask = 1<= 0; { 20 | if remain == 0 { 21 | cache, remain = src.Int63(), letterIdxMax 22 | } 23 | if idx := int(cache & letterIdxMask); idx < len(letterBytes) { 24 | b[i] = letterBytes[idx] 25 | i-- 26 | } 27 | cache >>= letterIdxBits 28 | remain-- 29 | } 30 | 31 | return string(b) 32 | } 33 | -------------------------------------------------------------------------------- /lib/util/safego/safe_goroutine.go: -------------------------------------------------------------------------------- 1 | package safego 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Iori372552686/GoOne/lib/api/logger" 6 | "runtime/debug" 7 | "time" 8 | ) 9 | 10 | // Go runs a safe goroutine 11 | func Go(f func()) { 12 | if f == nil { 13 | return 14 | } 15 | 16 | go SafeFunc(f) 17 | } 18 | 19 | // SafeFunc safe function call 20 | func SafeFunc(f func()) { 21 | defer func() { 22 | if r := recover(); r != nil { 23 | stack := string(debug.Stack()) 24 | fmt.Println(time.Now().String()) 25 | fmt.Println(r) 26 | fmt.Println(stack) 27 | logger.Fatalf("%v : %s ", r, stack) 28 | } 29 | }() 30 | f() 31 | } 32 | -------------------------------------------------------------------------------- /lib/util/safego/safe_test.go: -------------------------------------------------------------------------------- 1 | package safego 2 | 3 | import ( 4 | "context" 5 | "strconv" 6 | "sync" 7 | "testing" 8 | ) 9 | 10 | func TestSafeMap(t *testing.T) { 11 | var m map[string]string 12 | SafeFunc(context.Background(), func(c context.Context) { 13 | m["k"] = "v" 14 | }) 15 | m = make(map[string]string) 16 | wg := sync.WaitGroup{} 17 | wg.Add(2) 18 | Go(context.Background(), func(c context.Context) { 19 | for i := 0; i < 1000000; i++ { 20 | m["k"] = strconv.Itoa(i) 21 | } 22 | wg.Done() 23 | }) 24 | Go(context.Background(), func(c context.Context) { 25 | for i := 0; i < 1000000; i++ { 26 | m["k"] = strconv.Itoa(i) 27 | } 28 | wg.Done() 29 | }) 30 | wg.Wait() 31 | t.Log("safe") 32 | } 33 | -------------------------------------------------------------------------------- /lib/util/safego/singleflight.go: -------------------------------------------------------------------------------- 1 | package safego 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | ) 7 | 8 | //代表正在进行中,或已经结束的请求 9 | type call struct { 10 | sync.WaitGroup //避免重入:可能在f调用期间有n次调用,但是只执行一次 11 | val interface{} 12 | err error 13 | } 14 | 15 | //SingleFlight 管理不同key的请求 16 | type SingleFlight struct { 17 | lock sync.Mutex //保护m并发读写 18 | m map[string]*call 19 | } 20 | 21 | // Do 针对相同的key,无论Do被调用多少次,f只执行一次 22 | func (g *SingleFlight) Do(ctx context.Context, key string, f func(ctx context.Context) (interface{}, error)) (interface{}, error) { 23 | g.lock.Lock() 24 | if g.m == nil { 25 | g.m = make(map[string]*call) 26 | } 27 | //如果已有结果,返回 28 | if c, ok := g.m[key]; ok { 29 | g.lock.Unlock() 30 | c.Wait() //等待f调用结束了,再返回 31 | return c.val, c.err 32 | } 33 | c := new(call) 34 | c.Add(1) 35 | g.m[key] = c //缓存执行结果 36 | g.lock.Unlock() 37 | 38 | //调用函数 39 | SafeFunc(func() { 40 | c.val, c.err = f(ctx) 41 | }) 42 | 43 | c.Done() 44 | 45 | g.lock.Lock() 46 | delete(g.m, key) 47 | defer g.lock.Unlock() 48 | 49 | return c.val, c.err 50 | } 51 | -------------------------------------------------------------------------------- /lib/util/tos/dir.go: -------------------------------------------------------------------------------- 1 | package tos 2 | 3 | import ( 4 | "errors" 5 | "io/ioutil" 6 | "os" 7 | ) 8 | 9 | func ListDirFileName(dirPth string) (files []string, dirs []string, err error) { 10 | dir, err := ioutil.ReadDir(dirPth) 11 | if err != nil { 12 | return 13 | } 14 | for _, fi := range dir { 15 | if fi.IsDir() { 16 | dirs = append(dirs, fi.Name()) 17 | } else { 18 | files = append(files, fi.Name()) 19 | } 20 | } 21 | return 22 | } 23 | 24 | // ListDir 列出目录下所有文件(带完整路径) 25 | func ListDir(dirPth string) (files []string, dirs []string, err error) { 26 | return ListDirFullPath(dirPth) 27 | } 28 | 29 | // ListDirFullPath 列出目录下所有文件(带完整路径) 30 | func ListDirFullPath(dirPth string) (files []string, dirs []string, err error) { 31 | dir, err := ioutil.ReadDir(dirPth) 32 | if err != nil { 33 | return 34 | } 35 | PthSep := string(os.PathSeparator) 36 | 37 | for _, fi := range dir { 38 | if fi.IsDir() { 39 | dirs = append(dirs, dirPth+PthSep+fi.Name()) 40 | } else { 41 | files = append(files, dirPth+PthSep+fi.Name()) 42 | } 43 | } 44 | return 45 | } 46 | 47 | func IsFileExists(filePath string) bool { 48 | _, err := os.Stat(filePath) 49 | if err == nil { 50 | return true 51 | } 52 | if errors.Is(err, os.ErrNotExist) { 53 | return false 54 | } 55 | return false 56 | } 57 | -------------------------------------------------------------------------------- /lib/util/tos/port.go: -------------------------------------------------------------------------------- 1 | package tos 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | func GetFreePort() (*net.TCPListener, error) { 8 | addr, err := net.ResolveTCPAddr("tcp", ":0") 9 | if err != nil { 10 | return nil, err 11 | } 12 | 13 | l, err := net.ListenTCP("tcp", addr) 14 | if err != nil { 15 | return nil, err 16 | } 17 | return l, nil 18 | } 19 | 20 | func GetFreePorts(count int) ([]*net.TCPListener, error) { 21 | var ls []*net.TCPListener 22 | for i := 0; i < count; i++ { 23 | addr, err := net.ResolveTCPAddr("tcp", ":0") 24 | if err != nil { 25 | return nil, err 26 | } 27 | l, err := net.ListenTCP("tcp", addr) 28 | if err != nil { 29 | return nil, err 30 | } 31 | ls = append(ls, l) 32 | } 33 | return ls, nil 34 | } 35 | -------------------------------------------------------------------------------- /lib/util/tos/port_test.go: -------------------------------------------------------------------------------- 1 | package tos 2 | 3 | import ( 4 | "log" 5 | "testing" 6 | ) 7 | 8 | //单元测试 9 | func TestGetFreePort(t *testing.T) { 10 | port, err := GetFreePort() 11 | if err != nil { 12 | log.Println(err) 13 | } 14 | log.Println(port.Addr().String()) 15 | } 16 | 17 | //单元测试 18 | func TestGetFreePorts(t *testing.T) { 19 | port, err := GetFreePorts(3) 20 | if err != nil { 21 | log.Println(err) 22 | } 23 | for _, addr := range port { 24 | log.Println(addr.Addr().String()) 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /lib/util/tos/proc.go: -------------------------------------------------------------------------------- 1 | package tos 2 | 3 | import ( 4 | "os" 5 | "reflect" 6 | "runtime" 7 | "strings" 8 | "unsafe" 9 | ) 10 | 11 | var savedOSArgs []string 12 | 13 | func init() { 14 | argLen := len(os.Args) 15 | savedOSArgs = make([]string, len(os.Args)) 16 | for i := 0; i < argLen; i++ { 17 | savedOSArgs[i] = string([]byte(os.Args[i])) 18 | } 19 | } 20 | 21 | //GetSavedOSArgs 获取保存下来的系统参数 22 | func GetSavedOSArgs() (args []string) { 23 | argLen := len(savedOSArgs) 24 | args = make([]string, argLen) 25 | for i := 0; i < argLen; i++ { 26 | args[i] = savedOSArgs[i] 27 | } 28 | return 29 | } 30 | 31 | //SetProcName 设置进程名称(完整的进程名,包含进程的可执行路径,所有的参数以及额外自定义参数,需要使用者手动拼接os.Args) 32 | func SetProcName(name string) { 33 | argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0])) 34 | argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:] 35 | copy(argv0, name) 36 | argv0[len(name)] = 0 37 | } 38 | 39 | //SetProcNameEx 设置进程名(只需要设置自己需要的参数即可,例如进程启动的时候设置的-c/-v 等参数不需要设置) 40 | func SetProcNameEx(name string) { 41 | argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0])) 42 | argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:] 43 | argList := append(savedOSArgs, name) 44 | argStr := strings.Join(argList, " ") 45 | copy(argv0, argStr) 46 | argv0[len(argStr)] = 0 47 | } 48 | 49 | // ProcessName return process name 50 | func ProcessName() string { 51 | segs := strings.Split(savedOSArgs[0], string(os.PathSeparator)) 52 | var name string 53 | switch runtime.GOOS { 54 | case "windows": 55 | name = strings.Split(segs[len(segs)-1], ".")[0] 56 | case "linux": 57 | name = segs[len(segs)-1] 58 | } 59 | return name 60 | } 61 | -------------------------------------------------------------------------------- /lib/util/tos/sysinfo.go: -------------------------------------------------------------------------------- 1 | package tos 2 | 3 | import ( 4 | "errors" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func GetLocalIp() (addr string, err error) { 10 | var addrList []net.Addr 11 | addrList, err = net.InterfaceAddrs() 12 | 13 | if err != nil { 14 | return 15 | } 16 | 17 | for _, address := range addrList { 18 | // 检查ip地址判断是否回环地址 19 | if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() { 20 | if ipNet.IP.To4() != nil { 21 | addr = ipNet.IP.String() 22 | return 23 | } 24 | 25 | } 26 | } 27 | err = errors.New("Can not find the client ip address") 28 | return 29 | } 30 | 31 | func GetHostName() (name string) { 32 | name, _ = os.Hostname() 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /lib/util/version/version.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | /** 10 | * @Description: 11 | * @param: version 12 | * @return: int 13 | * @Author: Iori 14 | * @Date: 2022-07-05 20:12:53 15 | **/ 16 | 17 | func VersionToNum(version string) uint32 { 18 | arrStr := strings.Split(version, ".") 19 | var ipInt uint32 = 0 20 | var pos uint = 8 21 | 22 | for _, ipSeg := range arrStr { 23 | tempInt, _ := strconv.Atoi(ipSeg) 24 | ipInt = (ipInt << pos) | uint32(tempInt) 25 | } 26 | return ipInt 27 | } 28 | 29 | /** 30 | * @Description: 31 | * @param: num 32 | * @return: string 33 | * @Author: Iori 34 | * @Date: 2022-07-05 20:12:55 35 | **/ 36 | func NumToVersion(num int) string { 37 | mainV := num >> 16 38 | subV := ((0xff << 8) & num) >> 8 39 | minV := ((0xff << 0) & num) >> 0 40 | 41 | return fmt.Sprintf("%d.%d.%d", mainV, subV, minV) 42 | } 43 | -------------------------------------------------------------------------------- /lib/util/xlstrans/buid.bat: -------------------------------------------------------------------------------- 1 | set project_root_dir="../../../.." 2 | 3 | go build -o %project_root_dir%/excel/xlstrans.exe main.go parse_struct.go xls_to_pb.go xls_to_data.go xls_to_go.go xls_to_const.go xls_to_system_unlock.go 4 | pause -------------------------------------------------------------------------------- /lib/util/xlstrans/buid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | 5 | export GOPATH="${GOPATH}:${project_root_dir}/gopath" 6 | go build -o ../../../../excel/xlstrans main.go parse_struct.go xls_to_pb.go xls_to_data.go xls_to_go.go xls_to_const.go xls_to_system_unlock.go 7 | 8 | -------------------------------------------------------------------------------- /lib/util/xlstrans/xls_to_const.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/tealeg/xlsx" 6 | "io/ioutil" 7 | "strings" 8 | ) 9 | 10 | type XlsToConst struct { 11 | content string 12 | } 13 | 14 | func (c *XlsToConst) GenConstFile(sheet *xlsx.Sheet) { 15 | c.genHead() 16 | c.genFunc(sheet) 17 | c.writeFile() 18 | } 19 | 20 | func (c *XlsToConst) genHead() { 21 | c.content += ` 22 | package gamedata 23 | 24 | var Const ConstType 25 | 26 | type ConstType struct { 27 | } 28 | ` 29 | } 30 | 31 | func (c *XlsToConst) genFunc(sheet *xlsx.Sheet) { 32 | for i := 4; i < len(sheet.Rows); i++ { 33 | id := strings.TrimSpace(sheet.Cell(i, 0).String()) 34 | name := strings.TrimSpace(sheet.Cell(i, 1).String()) 35 | if id == "" || name == "" { 36 | continue 37 | } 38 | 39 | c.content += "func (* ConstType) " + name + "()" + " int32 {\n return int32(ConstConfMgr.GetOne(" + id + ").Value)\n}\n" 40 | } 41 | } 42 | 43 | func (c *XlsToConst) writeFile() { 44 | err := ioutil.WriteFile(targetGoDirPath+"/const.go", []byte(c.content), 0644) 45 | if err != nil { 46 | fmt.Println(err.Error()) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/util/xlstrans/xls_to_go.go: -------------------------------------------------------------------------------- 1 | /// 生成go的解析代码 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "github.com/iancoleman/strcase" 8 | "io/ioutil" 9 | "os" 10 | "strings" 11 | ) 12 | 13 | func GenGoMgrFile(templateFilePath string, structName string) { 14 | file, err := os.Open(templateFilePath) 15 | if err != nil { 16 | panic(err) 17 | } 18 | defer file.Close() 19 | 20 | content, err := ioutil.ReadAll(file) 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | dataFileName := "dataconfig_" + structName + ".config" 26 | 27 | str := string(content) 28 | str = strings.Replace(str, "{STRUCT_NAME}", strcase.ToCamel(structName), -1) 29 | str = strings.Replace(str, "{DATA_FILE_NAME}", dataFileName, -1) 30 | 31 | data := []byte(str) 32 | err = ioutil.WriteFile(targetGoDirPath+"/"+"mgr_"+structName+".go", data, 0644) 33 | if err != nil { 34 | fmt.Println(err.Error()) 35 | } 36 | 37 | } 38 | 39 | func GenAllIncludeFile(structNames []string) { 40 | str := "" 41 | str += "package gamedata\n\n" 42 | str += "import \"sync\"\n\n" 43 | 44 | for _, v := range structNames { 45 | str += "var " + strcase.ToCamel(v) + "Mgr " + strcase.ToCamel(v) + "MgrType\n" 46 | } 47 | 48 | str += "\nvar packageLocker sync.RWMutex\n" 49 | 50 | str += "\nfunc GameDataInit(basePath string) int {\n" 51 | str += " packageLocker.Lock()\n" 52 | str += " defer packageLocker.Unlock()\n\n" 53 | for _, v := range structNames { 54 | str += " " + strcase.ToCamel(v) + "Mgr" + ".InitFromFile(basePath)\n" 55 | } 56 | 57 | str += ` 58 | return 0 59 | } 60 | 61 | func RLock() { 62 | packageLocker.RLock() 63 | } 64 | 65 | func RUnlock() { 66 | packageLocker.RUnlock() 67 | }` 68 | 69 | err := ioutil.WriteFile(targetGoDirPath+"/all_data.go", []byte(str), 0644) 70 | if err != nil { 71 | fmt.Println(err.Error()) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /lib/util/xlstrans/xls_to_system_unlock.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/tealeg/xlsx" 6 | "io/ioutil" 7 | "strings" 8 | ) 9 | 10 | type XlsToSystemUnlock struct { 11 | content string 12 | } 13 | 14 | func (c *XlsToSystemUnlock) GenConstFile(sheet *xlsx.Sheet) { 15 | c.genHead() 16 | c.genFunc(sheet) 17 | c.writeFile() 18 | } 19 | 20 | func (c *XlsToSystemUnlock) genHead() { 21 | c.content += ` 22 | package gamedata 23 | 24 | var SystemUnlock SystemUnlockType 25 | 26 | type SystemUnlockType struct { 27 | } 28 | ` 29 | } 30 | 31 | func (c *XlsToSystemUnlock) genFunc(sheet *xlsx.Sheet) { 32 | for i := 4; i < len(sheet.Rows); i++ { 33 | id := strings.TrimSpace(sheet.Cell(i, 0).String()) 34 | name := strings.TrimSpace(sheet.Cell(i, 1).String()) 35 | if id == "" || name == "" { 36 | continue 37 | } 38 | 39 | c.content += "func (* SystemUnlockType) " + name + "FuncId()" + " int32 {\n return int32(SystemUnlockConfMgr.GetOne(" + id + ").Id)\n}\n" 40 | } 41 | } 42 | 43 | func (c *XlsToSystemUnlock) writeFile() { 44 | err := ioutil.WriteFile(targetGoDirPath+"/system_unlock.go", []byte(c.content), 0644) 45 | if err != nil { 46 | fmt.Println(err.Error()) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/util/zip/zip.go: -------------------------------------------------------------------------------- 1 | package zip 2 | 3 | import ( 4 | "bytes" 5 | "compress/zlib" 6 | "io" 7 | ) 8 | 9 | /** 10 | * @Description: encode 11 | * @param: data 12 | * @return: []byte 13 | * @Author: Iori 14 | **/ 15 | func ZipEncode(data []byte) []byte { 16 | var in bytes.Buffer 17 | 18 | z := zlib.NewWriter(&in) 19 | z.Write(data) 20 | z.Close() 21 | return in.Bytes() 22 | } 23 | 24 | /** 25 | * @Description: string encode 26 | * @param: data 27 | * @return: string 28 | * @Author: Iori 29 | * @Date: 2022-06-01 15:12:16 30 | **/ 31 | func ZipEncodeStr(data string) string { 32 | var in bytes.Buffer 33 | 34 | z := zlib.NewWriter(&in) 35 | z.Write([]byte(data)) 36 | z.Close() 37 | return in.String() 38 | } 39 | 40 | /** 41 | * @Description: decode 42 | * @param: data 43 | * @return: []byte 44 | * @Author: Iori 45 | * @Date: 2022-06-01 15:10:03 46 | **/ 47 | func ZipDecode(data []byte) ([]byte, error) { 48 | var out bytes.Buffer 49 | var in bytes.Buffer 50 | 51 | in.Write(data) 52 | r, err := zlib.NewReader(&in) 53 | if err != nil { 54 | return nil, err 55 | } 56 | 57 | r.Close() 58 | io.Copy(&out, r) 59 | 60 | return out.Bytes(), nil 61 | } 62 | 63 | func ZipDecodeStr(data string) string { 64 | var out bytes.Buffer 65 | var in bytes.Buffer 66 | 67 | in.Write([]byte(data)) 68 | r, _ := zlib.NewReader(&in) 69 | r.Close() 70 | io.Copy(&out, r) 71 | return out.String() 72 | } 73 | -------------------------------------------------------------------------------- /lib/web/rest/Controller.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | _ "github.com/go-sql-driver/mysql" 6 | 7 | "fmt" 8 | 9 | "strings" 10 | ) 11 | 12 | type Controller struct { 13 | Auth bool 14 | Data interface{} 15 | } 16 | 17 | //对未定义的路由规则进行处理 18 | func NoRoute(ctx *gin.Context) { 19 | // todo 20 | //如果不存在则跳转出错页面 21 | } 22 | 23 | func NoMethod(ctx *gin.Context) { 24 | uri := ctx.Request.RequestURI 25 | fmt.Printf("NoMethod" + uri) 26 | uri = strings.TrimLeft(uri, "/") 27 | uri = strings.TrimSuffix(uri, ".shtml") 28 | //ctx.HTML(http.StatusOK, model+"/"+action+".html", gin.H{"title": "test"}) 29 | ctx.HTML(200, uri+".html", "Q") 30 | } 31 | -------------------------------------------------------------------------------- /lib/web/rest/Crypto.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | "strings" 7 | ) 8 | 9 | func Md5Encode(arg0 string) string { 10 | h := md5.New() 11 | h.Write([]byte(arg0)) 12 | cipherStr := h.Sum(nil) 13 | 14 | return strings.ToLower(hex.EncodeToString(cipherStr)) // 输出加密结果 15 | } 16 | 17 | func Md5EncodeV2(arg0 string) string { 18 | h := md5.New() 19 | h.Write([]byte(arg0)) 20 | cipherStr := h.Sum(nil) 21 | 22 | return strings.ToUpper(hex.EncodeToString(cipherStr)) 23 | } 24 | -------------------------------------------------------------------------------- /lib/web/rest/Func.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import ( 4 | _ "github.com/go-sql-driver/mysql" 5 | 6 | "html/template" 7 | ) 8 | 9 | var restFuncMap = make(template.FuncMap) 10 | 11 | func init() { 12 | restFuncMap["ctxpath"] = ctxpath 13 | restFuncMap["apiurl"] = apiurl 14 | restFuncMap["version"] = version 15 | restFuncMap["hello"] = hello 16 | restFuncMap["asset"] = asset 17 | } 18 | 19 | func asset() string { 20 | return "" 21 | } 22 | 23 | func GetFuncMap() template.FuncMap { 24 | return restFuncMap 25 | } 26 | 27 | func hello(d string) string { 28 | return "hello " + d 29 | } 30 | 31 | func ctxpath() string { 32 | return "" 33 | } 34 | 35 | func apiurl(uri string) string { 36 | return uri 37 | } 38 | 39 | func version() string { 40 | return "v1.1.0" //todo 41 | } 42 | -------------------------------------------------------------------------------- /lib/web/rest/JsonTime.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type JsonDateTime time.Time 8 | type JsonDate time.Time 9 | type JsonTime time.Time 10 | 11 | const ( 12 | dateTimeFormart = "2006-01-02 15:04:05" 13 | dateFormart = "2006-01-02" 14 | timeFormart = "15:04:05" 15 | ) 16 | 17 | func (p *JsonDateTime) UnmarshalJSON(data []byte) (err error) { 18 | now, err := time.ParseInLocation(`"`+dateTimeFormart+`"`, string(data), time.Local) 19 | *p = JsonDateTime(now) 20 | return 21 | } 22 | func (p *JsonDate) UnmarshalJSON(data []byte) (err error) { 23 | now, err := time.ParseInLocation(`"`+dateFormart+`"`, string(data), time.Local) 24 | *p = JsonDate(now) 25 | return 26 | } 27 | func (p *JsonTime) UnmarshalJSON(data []byte) (err error) { 28 | now, err := time.ParseInLocation(`"`+timeFormart+`"`, string(data), time.Local) 29 | *p = JsonTime(now) 30 | return 31 | } 32 | func (c JsonDateTime) MarshalJSON() ([]byte, error) { 33 | data := make([]byte, 0) 34 | data = append(data, '"') 35 | data = time.Time(c).AppendFormat(data, dateTimeFormart) 36 | data = append(data, '"') 37 | return data, nil 38 | } 39 | func (c JsonDate) MarshalJSON() ([]byte, error) { 40 | data := make([]byte, 0) 41 | data = append(data, '"') 42 | data = time.Time(c).AppendFormat(data, dateFormart) 43 | data = append(data, '"') 44 | return data, nil 45 | } 46 | func (c JsonTime) MarshalJSON() ([]byte, error) { 47 | data := make([]byte, 0) 48 | data = append(data, '"') 49 | data = time.Time(c).AppendFormat(data, timeFormart) 50 | data = append(data, '"') 51 | return data, nil 52 | } 53 | func (c JsonDateTime) String() string { 54 | return time.Time(c).Format(dateTimeFormart) 55 | } 56 | 57 | func (c JsonTime) String() string { 58 | return time.Time(c).Format(timeFormart) 59 | } 60 | -------------------------------------------------------------------------------- /lib/web/rest/Result.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | func Result(ctx *gin.Context, code int32, data interface{}, msg string) { 10 | ctx.JSON(http.StatusOK, gin.H{"code": code, "data": data, "msg": msg}) 11 | } 12 | 13 | func ResultErrCode(ctx *gin.Context, code int32, data interface{}, msg string) { 14 | ctx.JSON(http.StatusOK, gin.H{"code": code, "data": data, "msg": msg}) 15 | } 16 | 17 | func ResultOk(ctx *gin.Context, data interface{}) { 18 | ctx.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "data": data, "msg": ""}) 19 | } 20 | func ResultList(ctx *gin.Context, data interface{}, total int64) { 21 | ctx.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "rows": data, "msg": "", "total": total}) 22 | } 23 | func ResultOkMsg(ctx *gin.Context, data interface{}, msg string) { 24 | ctx.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "data": data, "msg": msg}) 25 | } 26 | 27 | func ResultFail(ctx *gin.Context, err interface{}) { 28 | ctx.JSON(http.StatusOK, gin.H{"code": http.StatusBadRequest, "data": nil, "msg": err}) 29 | } 30 | 31 | func ResultFailData(ctx *gin.Context, data interface{}, err interface{}) { 32 | ctx.JSON(http.StatusOK, gin.H{"code": http.StatusBadRequest, "data": data, "msg": err}) 33 | } 34 | -------------------------------------------------------------------------------- /lib/web/rest/SessionUtil.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | sessions "github.com/tommy351/gin-sessions" 6 | ) 7 | 8 | func SetSession(ctx *gin.Context, k string, o interface{}) { 9 | session := sessions.Get(ctx) 10 | session.Set(k, o) 11 | session.Save() 12 | } 13 | 14 | func GetSession(ctx *gin.Context, k string) interface{} { 15 | session := sessions.Get(ctx) 16 | return session.Get(k) 17 | } 18 | 19 | func SaveUser(ctx *gin.Context, user interface{}) { 20 | SetSession(ctx, "user", user) 21 | } 22 | 23 | func LoadUser(ctx *gin.Context) interface{} { 24 | return GetSession(ctx, "user") 25 | } 26 | 27 | func SaveRoleId(ctx *gin.Context, roleId interface{}) { 28 | session := sessions.Get(ctx) 29 | 30 | session.Set("roleid", roleId) 31 | session.Save() 32 | } 33 | 34 | func LoadRoleId(ctx *gin.Context) interface{} { 35 | session := sessions.Get(ctx) 36 | o := session.Get("roleid") 37 | return o 38 | 39 | } 40 | 41 | func ClearAllSession(ctx *gin.Context) { 42 | session := sessions.Get(ctx) 43 | session.Clear() 44 | session.Save() 45 | return 46 | } 47 | -------------------------------------------------------------------------------- /lib/web/web_gin/config.go: -------------------------------------------------------------------------------- 1 | package web_gin 2 | 3 | type Config struct { 4 | IP string `json:"ip" yaml:"ip"` // ip addr 5 | Port int `json:"port" yaml:"port"` // port 端口 6 | SessionName string `json:"session_name" yaml:"session_name"` //session名 7 | AuthEnable bool `json:"auth_enable" yaml:"auth_enable"` //签名开关 8 | Mode string `json:"mode" yaml:"mode"` //http模式 9 | } 10 | -------------------------------------------------------------------------------- /lib/web/web_gin/handler_process.go: -------------------------------------------------------------------------------- 1 | package web_gin 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | var ( 10 | handlers = make(map[string]ICmdWebHandler) 11 | handlersRWMutex sync.RWMutex 12 | ) 13 | 14 | /** 15 | * @Description: reg 16 | * @param: key 17 | * @param: value 18 | * @Author: Iori 19 | * @Date: 2022-04-26 17:31:33 20 | **/ 21 | func Register(key string, value ICmdWebHandler) { 22 | handlersRWMutex.Lock() 23 | defer handlersRWMutex.Unlock() 24 | handlers[key] = value 25 | 26 | return 27 | } 28 | 29 | /** 30 | * @Description: get handlers 31 | * @param: key 32 | * @return: value 33 | * @return: ok 34 | * @Author: Iori 35 | * @Date: 2022-04-26 17:31:21 36 | **/ 37 | func GetHandlers(key string) (value ICmdWebHandler, ok bool) { 38 | handlersRWMutex.RLock() 39 | defer handlersRWMutex.RUnlock() 40 | 41 | value, ok = handlers[key] 42 | return 43 | } 44 | 45 | /* ICmdWsHandler 46 | * @Description: 47 | */ 48 | type ICmdWebHandler interface { 49 | ProcessCmd(cParams, data *map[string]interface{}) *gin.H 50 | } 51 | -------------------------------------------------------------------------------- /lib/web/web_gin/http.go: -------------------------------------------------------------------------------- 1 | package web_gin 2 | 3 | import ( 4 | "errors" 5 | "github.com/Iori372552686/GoOne/lib/api/logger" 6 | "github.com/Iori372552686/GoOne/lib/web/rest" 7 | "time" 8 | 9 | ginglog "github.com/szuecs/gin-glog" 10 | sessions "github.com/tommy351/gin-sessions" 11 | 12 | "strconv" 13 | 14 | "github.com/gin-gonic/gin" 15 | ) 16 | 17 | /** 18 | * @Description: Run gin start the server 19 | * @param: http_port 20 | * @param: mode 21 | * @param: session_name 22 | * @param: load_routers 23 | * @return: error 24 | * @Author: Iori 25 | * @Date: 2022-02-28 11:27:27 26 | **/ 27 | func RunGin(conf Config, load_routers func(router *gin.Engine)) error { 28 | if conf.Port <= 0 { 29 | return errors.New("port args err!") 30 | } 31 | 32 | //mode 33 | switch conf.Mode { 34 | case "debug": 35 | gin.SetMode(gin.DebugMode) 36 | case "test": 37 | gin.SetMode(gin.TestMode) 38 | default: 39 | gin.SetMode(gin.ReleaseMode) 40 | } 41 | 42 | router := gin.New() 43 | router.Use(rest.Cors()) 44 | router.Use(ginglog.Logger(3*time.Second), gin.Recovery()) 45 | router.Use(sessions.Middleware(conf.SessionName, sessions.NewCookieStore([]byte(conf.SessionName)))) 46 | //router.NoRoute(rest.NoRoute) 47 | //router.NoMethod(rest.NoMethod) 48 | 49 | //loadRoutes 50 | load_routers(router) 51 | go router.Run(conf.IP + ":" + strconv.Itoa(conf.Port)) 52 | logger.Infof("------ Http Gin Server Running by %v:%v ------", conf.IP, conf.Port) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /module/drop/mymath.go: -------------------------------------------------------------------------------- 1 | package drop 2 | 3 | import "math/rand" 4 | 5 | // 返回idx 6 | func WeightedRandomSelect(weightList []int32) int32 { 7 | totalWeight := 0 8 | for _, v := range weightList { 9 | totalWeight += int(v) 10 | } 11 | 12 | r := rand.Intn(totalWeight) 13 | tmpWeight := totalWeight 14 | for i, v := range weightList { 15 | tmpWeight -= int(v) 16 | if r >= tmpWeight { 17 | return int32(i) 18 | } 19 | } 20 | return int32(len(weightList) - 1) 21 | } 22 | 23 | // 带权随机出n(>=1)个 24 | // 比较笨的办法 25 | // 一个一个的抽 26 | func WeightedRandomSelectN(weightList []int32, n int32) *[]int32 { 27 | ret := make([]int32, 0) 28 | wlen := int32(len(weightList)) 29 | if n <= 0 || wlen <= 0 { 30 | return nil 31 | } 32 | 33 | tmpWeight := make([]int32, wlen) 34 | copy(tmpWeight, weightList) 35 | for i := int32(0); i < n && i < wlen; i++ { 36 | idx := WeightedRandomSelect(tmpWeight) 37 | ret = append(ret, idx) 38 | tmpWeight[idx] = 0 39 | } 40 | return &ret 41 | } 42 | 43 | func RandomSelectN(max, n int32) *[]int32 { 44 | // TODO 比较粗暴,也可以用一个数组然后shuffle 45 | w := make([]int32, max) 46 | for i := int32(0); i < max; i++ { 47 | w[i] = 1 48 | } 49 | return WeightedRandomSelectN(w, n) 50 | } 51 | -------------------------------------------------------------------------------- /src/connsvr/cmd_handler/register.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/Iori372552686/GoOne/src/connsvr/globals" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | ) 8 | 9 | // 所有的命令字对应的go需要在这里先注册 10 | func RegCmd() { 11 | logger.Infof("register transaction commands") 12 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_CONN_BROADCAST_REQ, Broadcast) 13 | } 14 | -------------------------------------------------------------------------------- /src/connsvr/cmd_handler/trans_broadcast.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/cmd_handler" 5 | "github.com/Iori372552686/GoOne/lib/api/sharedstruct" 6 | "github.com/Iori372552686/GoOne/src/connsvr/globals" 7 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 8 | ) 9 | 10 | func Broadcast(c cmd_handler.IContext, data []byte) g1_protocol.ErrorCode { 11 | req := &g1_protocol.ConnBroadcastReq{} 12 | 13 | err := c.ParseMsg(data, req) 14 | if err != nil { 15 | return g1_protocol.ErrorCode_ERR_MARSHAL 16 | } 17 | 18 | csPacketHeader := sharedstruct.CSPacketHeader{ 19 | Uid: c.Uid(), 20 | Cmd: req.Cmd, 21 | BodyLen: uint32(len(req.Body)), 22 | } 23 | 24 | //globals.ConnTcpSvr.BroadcastByZone(0, csPacketHeader.ToBytes(), req.Body) 25 | globals.ConnWsSvr.BroadcastByZone(0, csPacketHeader.ToBytes(), req.Body) 26 | return g1_protocol.ErrorCode_ERR_OK 27 | } 28 | -------------------------------------------------------------------------------- /src/connsvr/globals/globals.go: -------------------------------------------------------------------------------- 1 | package globals 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/http_sign" 5 | "github.com/Iori372552686/GoOne/lib/api/rest_api" 6 | "github.com/Iori372552686/GoOne/lib/net/net_mgr" 7 | "github.com/Iori372552686/GoOne/lib/service/transaction" 8 | ) 9 | 10 | var ( 11 | TransMgr = transaction.NewTransactionMgr() 12 | ConnTcpSvr = net_mgr.NewTcpSvr() 13 | ConnWsSvr = net_mgr.NewWsTcpSvr() 14 | SignMgr = http_sign.NewSignMgr() 15 | RestMgr = rest_api.NewRestApiMgr() 16 | ) 17 | -------------------------------------------------------------------------------- /src/connsvr/login/login.go: -------------------------------------------------------------------------------- 1 | package login 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/util/convert" 5 | "github.com/Iori372552686/GoOne/src/connsvr/globals" 6 | ) 7 | 8 | // php中台通讯消息体 9 | type MiddleMsgDefault struct { 10 | Status bool `json:"status"` 11 | Msg string 12 | } 13 | 14 | type MiddleMsgRole struct { 15 | MiddleMsgDefault 16 | Data MiddleRole `json:"data"` 17 | } 18 | 19 | // 中台角色信息 20 | type MiddleRole struct { 21 | Id int64 `json:"id"` //rid 22 | UserId int64 `json:"user_id"` //中台aid 23 | ChannelId int64 `json:"chan_id"` 24 | Status int8 `json:"status"` //1正常 其他异常 25 | SiteId int64 `json:"site_id"` //站点id 26 | Balance int64 `json:"balance"` //余额 27 | Freeze int64 `json:"freeze"` //冻结金额 28 | UpdateTime int64 `json:"update_time"` 29 | CreateTime int64 `json:"create_time"` 30 | } 31 | 32 | // check auth by accsvr 33 | func OnCheckAuthByAccSvr(accId string, token string, serverid uint32, loginType string) (bool, uint64) { 34 | header := &map[string]string{ 35 | "Authorization": token, 36 | "Content-type": "application/json", 37 | } 38 | 39 | body := &map[string]interface{}{ 40 | "channel_id": serverid, 41 | "account_id": accId, 42 | "login_type": loginType, 43 | } 44 | 45 | rsqBody, err := globals.RestMgr.GetRestIns().SignPostV2(header, nil, body) 46 | if err != nil { 47 | return false, 0 48 | } 49 | 50 | var result MiddleMsgRole 51 | convert.JsonToStruct(convert.Bytes2str(rsqBody), &result) 52 | if result.Status == true { 53 | // if result["ret"] == "true" { 54 | return true, uint64(result.Data.Id) 55 | } 56 | 57 | return false, 0 58 | } 59 | -------------------------------------------------------------------------------- /src/connsvr/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | 6 | "github.com/Iori372552686/GoOne/lib/api/logger" 7 | "github.com/Iori372552686/GoOne/lib/service/application" 8 | ) 9 | 10 | func main() { 11 | flag.Parse() 12 | defer logger.Flush() 13 | 14 | application.Init(&AppSvrImpl{}) 15 | application.Run() 16 | } 17 | -------------------------------------------------------------------------------- /src/infosvr/cmd_handler/register.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/Iori372552686/GoOne/src/infosvr/globals" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | ) 8 | 9 | // 所有的命令字对应的go需要在这里先注册 10 | func RegCmd() { 11 | logger.Infof("register transaction commands") 12 | 13 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_INFO_GET_BRIEF_INFO_REQ, GetBriefInfo) 14 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_INFO_GET_ICON_DESC_REQ, GetIconDesc) 15 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_INFO_INNER_SET_BRIEF_INFO_REQ, SetBriefInfo) 16 | } 17 | -------------------------------------------------------------------------------- /src/infosvr/globals/globals.go: -------------------------------------------------------------------------------- 1 | package globals 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/service/transaction" 5 | "github.com/Iori372552686/GoOne/src/infosvr/info" 6 | ) 7 | 8 | var TransMgr = transaction.NewTransactionMgr() 9 | var InfoMgr = info.NewInfoMgr() 10 | -------------------------------------------------------------------------------- /src/infosvr/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | 6 | "github.com/Iori372552686/GoOne/lib/api/logger" 7 | "github.com/Iori372552686/GoOne/lib/service/application" 8 | ) 9 | 10 | func main() { 11 | flag.Parse() 12 | defer logger.Flush() 13 | 14 | application.Init(&InfoSvrImpl{}) 15 | application.Run() 16 | } 17 | -------------------------------------------------------------------------------- /src/mainsvr/cmd_handler/c2s_main_mall.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/common/gamedata/repository/mall_config" 5 | "github.com/Iori372552686/GoOne/lib/api/cmd_handler" 6 | "github.com/Iori372552686/GoOne/src/mainsvr/role" 7 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 8 | ) 9 | 10 | func MallBuyPackage(c cmd_handler.IContext, data []byte, myRole *role.Role) g1_protocol.ErrorCode { 11 | req := &g1_protocol.MallBuyPackageReq{} 12 | rsp := &g1_protocol.MallBuyPackageRsp{Ret: &g1_protocol.Ret{Code: g1_protocol.ErrorCode_ERR_OK}} 13 | err := c.ParseMsg(data, req) 14 | if err != nil { 15 | return g1_protocol.ErrorCode_ERR_MARSHAL 16 | } 17 | 18 | defer c.SendMsgBack(rsp) 19 | rsp.Ret.Code = myRole.MallCheckBuyCondition(req.ConfId) 20 | if rsp.Ret.Code != 0 { 21 | return g1_protocol.ErrorCode_ERR_ARGV 22 | } 23 | 24 | conf := mall_config.GetById(req.ConfId) 25 | if conf == nil { 26 | rsp.Ret.Code = g1_protocol.ErrorCode_ERR_CONF 27 | return rsp.Ret.Code 28 | } 29 | 30 | _, rsp.Ret.Code = myRole.ItemCheckReduce(conf.CostItemID, int64(conf.CostItemCnt)) 31 | if rsp.Ret.Code != g1_protocol.ErrorCode_ERR_OK { 32 | return rsp.Ret.Code 33 | } 34 | 35 | //如果是充值购买的礼包就走充值 36 | if int32(g1_protocol.EItemID_ACECOIN) == conf.CostItemID { 37 | //ret = RechargeAdd(conf.Rmb, myRole) 38 | } else { 39 | rsp.Ret.Code = myRole.ItemExchange(conf.CostItemID, int64(conf.CostItemCnt), conf.PackageID, 40 | 1, &role.Reason{g1_protocol.Reason_REASON_MALL_PACKAGE, req.ConfId}) 41 | if rsp.Ret.Code != g1_protocol.ErrorCode_ERR_OK { 42 | return rsp.Ret.Code 43 | } 44 | } 45 | 46 | myRole.MallAddBuyCount(req.ConfId) 47 | myRole.SyncDataToClient(g1_protocol.ERoleSectionFlag_MALL_INFO | g1_protocol.ERoleSectionFlag_INVENTORY_INFO | g1_protocol.ERoleSectionFlag_BASIC_INFO) 48 | return rsp.Ret.Code 49 | } 50 | -------------------------------------------------------------------------------- /src/mainsvr/cmd_handler/role_adapter.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/cmd_handler" 5 | "github.com/Iori372552686/GoOne/src/mainsvr/globals" 6 | "github.com/Iori372552686/GoOne/src/mainsvr/role" 7 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 8 | ) 9 | 10 | type IRoleCmd func(c cmd_handler.IContext, data []byte, myRole *role.Role) g1_protocol.ErrorCode 11 | 12 | type roleAdapter struct { 13 | roleCmd IRoleCmd 14 | } 15 | 16 | func NewRoleAdapter(roleCmd IRoleCmd) cmd_handler.CmdHandlerFunc { 17 | a := new(roleAdapter) 18 | a.roleCmd = roleCmd 19 | return a.ProcessCmd 20 | } 21 | 22 | func (t *roleAdapter) ProcessCmd(c cmd_handler.IContext, data []byte) g1_protocol.ErrorCode { 23 | myRole := globals.RoleMgr.GetOrLoadRole(c.Uid(), c) 24 | if myRole == nil { 25 | return g1_protocol.ErrorCode_ERR_ARGV 26 | } 27 | 28 | return t.roleCmd(c, data, myRole) 29 | } 30 | -------------------------------------------------------------------------------- /src/mainsvr/globals/globals.go: -------------------------------------------------------------------------------- 1 | package globals 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/service/transaction" 5 | "github.com/Iori372552686/GoOne/lib/util/idgen" 6 | "github.com/Iori372552686/GoOne/src/mainsvr/role" 7 | ) 8 | 9 | var TransMgr = transaction.NewTransactionMgr() 10 | var RoleMgr = role.NewRoleMgr() 11 | var IDGen *idgen.TIDGen 12 | -------------------------------------------------------------------------------- /src/mainsvr/globals/rds/redis.go: -------------------------------------------------------------------------------- 1 | package rds 2 | 3 | import "github.com/Iori372552686/GoOne/lib/db/redis" 4 | 5 | var RedisMgr = redis.NewRedisMgr() 6 | -------------------------------------------------------------------------------- /src/mainsvr/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | _ "net/http/pprof" 6 | 7 | "github.com/Iori372552686/GoOne/lib/api/logger" 8 | "github.com/Iori372552686/GoOne/lib/service/application" 9 | ) 10 | 11 | func main() { 12 | flag.Parse() 13 | defer logger.Flush() 14 | 15 | application.Init(&MainSvrImpl{}) 16 | application.Run() 17 | } 18 | -------------------------------------------------------------------------------- /src/mainsvr/role/drop.go: -------------------------------------------------------------------------------- 1 | /// 掉落相关 2 | 3 | package role 4 | 5 | import ( 6 | "math/rand" 7 | 8 | "github.com/Iori372552686/GoOne/common/gamedata/repository/drop_item_confing" 9 | "github.com/Iori372552686/GoOne/module/drop" 10 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 11 | ) 12 | 13 | const ( 14 | MAX_PROBABILITY = 10000 15 | ) 16 | 17 | func (r *Role) DropGetItemByDropID(dropID int32) *[]*g1_protocol.PbItem { 18 | items := make([]*g1_protocol.PbItem, 0) 19 | 20 | r.Debugf("DROP|get drop: %d", dropID) 21 | dropByWeight := make([]*g1_protocol.DropItemConfing, 0) 22 | weightList := make([]int32, 0) 23 | drop_item_confing.Range(func(v *g1_protocol.DropItemConfing) bool { 24 | if v.DropId != dropID { 25 | return true 26 | } 27 | 28 | if v.DropWay == int32(g1_protocol.EItemDropWay_CERTAIN) { // 一定掉落 29 | item := g1_protocol.PbItem{Id: v.ItemId, Count: v.Count} 30 | items = append(items, &item) 31 | r.Debugf("DROP|add certain: %v", item) 32 | } else if v.DropWay == int32(g1_protocol.EItemDropWay_PROBABILITY) { // 概率掉落 33 | randV := int32(rand.Intn(MAX_PROBABILITY)) 34 | if randV < v.Probability { 35 | item := g1_protocol.PbItem{Id: v.ItemId, Count: v.Count} 36 | items = append(items, &item) 37 | r.Debugf("DROP|add probability: %v", item) 38 | } 39 | } else if v.DropWay == int32(g1_protocol.EItemDropWay_WEIGHT) { // 分组权重掉落 40 | if v.GetProbability() == 0 { 41 | v.Probability = 1 42 | } //容错,没有得话默认1 43 | dropByWeight = append(dropByWeight, v) 44 | weightList = append(weightList, v.Probability) 45 | r.Debugf("DROP|add weight: %v", v) 46 | } 47 | 48 | return true 49 | }) 50 | 51 | if len(dropByWeight) > 0 { 52 | idx := drop.WeightedRandomSelect(weightList) 53 | item := g1_protocol.PbItem{Id: dropByWeight[idx].ItemId, Count: dropByWeight[idx].Count} 54 | items = append(items, &item) 55 | } 56 | 57 | r.Debugf("DROP| items: %v", items) 58 | return &items 59 | } 60 | -------------------------------------------------------------------------------- /src/mainsvr/role/game.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | import ( 4 | util "github.com/Iori372552686/GoOne/lib/util/slices" 5 | pb "github.com/Iori372552686/game_protocol/protocol" 6 | ) 7 | 8 | func (r *Role) AddPlayRoomID(roomId uint64) pb.ErrorCode { 9 | info := r.PbRole.GameInfo 10 | 11 | if info.PlayRoomIds == nil { 12 | info.PlayRoomIds = make([]uint64, 0) 13 | } 14 | 15 | for _, v := range info.PlayRoomIds { 16 | if v == roomId { 17 | return pb.ErrorCode_ERR_OK 18 | } 19 | } 20 | 21 | info.PlayRoomIds = util.InsertAtTail(info.PlayRoomIds, roomId, 3) 22 | return pb.ErrorCode_ERR_OK 23 | } 24 | 25 | func (r *Role) RemovePlayRoomID(roomId uint64) pb.ErrorCode { 26 | info := r.PbRole.GameInfo 27 | 28 | if info.PlayRoomIds != nil { 29 | info.PlayRoomIds, _ = util.Remove(info.PlayRoomIds, roomId) 30 | } 31 | 32 | return pb.ErrorCode_ERR_OK 33 | } 34 | 35 | func (r *Role) ClearPlayRoomInfo() pb.ErrorCode { 36 | info := r.PbRole.GameInfo 37 | 38 | info.PlayRoomIds = make([]uint64, 0) 39 | return pb.ErrorCode_ERR_OK 40 | } 41 | -------------------------------------------------------------------------------- /src/mainsvr/role/guide.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | import ( 4 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 5 | ) 6 | 7 | func (r *Role) GuideCompleted(id int32) int { 8 | // 是否已经存在 9 | for _, v := range r.PbRole.GuideInfo.IdLis { 10 | if v == id { 11 | return int(g1_protocol.ErrorCode_ERR_GUIDE_IS_EXIST) 12 | } 13 | } 14 | r.PbRole.GuideInfo.IdLis = append(r.PbRole.GuideInfo.IdLis, id) 15 | return 0 16 | } 17 | 18 | func (r *Role) GuideInProgress(id int32) int { 19 | r.PbRole.GuideInfo.CurId = id 20 | return 0 21 | } 22 | -------------------------------------------------------------------------------- /src/mainsvr/role/mail.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/cmd_handler" 5 | "github.com/Iori372552686/GoOne/module/misc" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | ) 8 | 9 | // 添加邮件,这里一般是在trans中执行的,所以要加上cmd_handle参数 10 | func (r *Role) MailAdd(c cmd_handler.IContext, mailType int32, confID int32, attach *[]*g1_protocol.PbItem) int { 11 | mail := &g1_protocol.PbMail{} 12 | mail.Type = mailType 13 | mail.ConfId = confID 14 | mail.CreateTime = r.Now() 15 | if attach != nil { 16 | mail.AttachList = *attach 17 | } 18 | mail.Sender = c.Uid() 19 | 20 | req := &g1_protocol.MailInnerAddMailReq{} 21 | req.MailList = append(req.MailList, mail) 22 | rsp := &g1_protocol.MailInnerAddMailRsp{Ret: &g1_protocol.Ret{}} 23 | err := c.CallMsgBySvrType(misc.ServerType_MailSvr, g1_protocol.CMD_MAIL_INNER_ADD_MAIL_REQ, req, rsp) 24 | if err != nil { 25 | c.Errorf("send mail error, %v", err) 26 | return -1 27 | } 28 | 29 | return int(rsp.Ret.Code) 30 | } 31 | -------------------------------------------------------------------------------- /src/mainsvr/role/mall.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/common/gamedata/repository/mall_config" 5 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 6 | ) 7 | 8 | func (r *Role) MallGetItem(confId int32) *g1_protocol.PbMallItem { 9 | info := r.PbRole.MallInfo 10 | 11 | if info.ItemMap == nil { 12 | info.ItemMap = make(map[int32]*g1_protocol.PbMallItem) 13 | if info.ItemMap[confId] == nil { 14 | info.ItemMap[confId] = &g1_protocol.PbMallItem{ConfId: confId} 15 | } 16 | } 17 | 18 | return info.ItemMap[confId] 19 | } 20 | 21 | func (r *Role) MallDailyRefresh() { 22 | info := r.PbRole.MallInfo 23 | for _, v := range info.ItemMap { 24 | v.DailyBuyCount = 0 25 | } 26 | } 27 | 28 | func (r *Role) MallAddBuyCount(confId int32) { 29 | item := r.MallGetItem(confId) 30 | item.DailyBuyCount++ 31 | item.TotalBuyCount++ 32 | } 33 | 34 | func (r *Role) MallCheckBuyCondition(confId int32) g1_protocol.ErrorCode { 35 | conf := mall_config.GetById(confId) 36 | if conf == nil { 37 | return g1_protocol.ErrorCode_ERR_CONF 38 | } 39 | 40 | /* now := int64(r.Now()) 41 | if (conf.BeginTime > 0 && now < conf.BeginTime) || 42 | (conf.EndTime > 0 && now > conf.EndTime) { 43 | return g1_protocol.ErrorCode_ERR_MALL_OUT_OF_TIME 44 | }*/ 45 | 46 | item := r.MallGetItem(confId) 47 | if item.DailyBuyCount >= conf.DailyBuyLimit && conf.DailyBuyLimit > 0 { 48 | return g1_protocol.ErrorCode_ERR_MALL_DAILY_LIMIT 49 | } 50 | 51 | if item.TotalBuyCount >= conf.BuyLimit && conf.BuyLimit > 0 { 52 | return g1_protocol.ErrorCode_ERR_MALL_BUY_LIMIT 53 | } 54 | 55 | return 0 56 | } 57 | -------------------------------------------------------------------------------- /src/mainsvr/role/open_function.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | // 同步功能开放 4 | func (r *Role) SyncOpenFuncData() { 5 | 6 | } 7 | 8 | func (r *Role) FuncIsOpen(openFuncId int32) bool { 9 | if r.PbRole.OpenFunInfo.IsAllOpen { 10 | return true 11 | } 12 | //return r.PbRole.OpenFunInfo.Data[openFuncId] 13 | for _, v := range r.PbRole.OpenFunInfo.Data { 14 | if v == openFuncId { 15 | return true 16 | } 17 | } 18 | return false 19 | } 20 | -------------------------------------------------------------------------------- /src/mainsvr/role/reason.go: -------------------------------------------------------------------------------- 1 | package role 2 | 3 | import pb "github.com/Iori372552686/game_protocol/protocol" 4 | 5 | // 数据变化原因 6 | type Reason struct { 7 | Reason pb.Reason 8 | Scene int32 9 | } 10 | -------------------------------------------------------------------------------- /src/mysqlsvr/cmd_handler/register.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/Iori372552686/GoOne/src/mysqlsvr/globals" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | ) 8 | 9 | // 所有的命令字对应的go需要在这里先注册 10 | func RegCmd() { 11 | logger.Infof("register transaction commands") 12 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_MYSQL_INNER_UPDATE_ROLE_INFO_REQ, UpdateRoleInfo) 13 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_MYSQL_INNER_SEARCH_ROLE_REQ, SearchRole) 14 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_MYSQL_INNER_UPDATE_REQ, UpdateRequest) // 更新数据库 15 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_MYSQL_INNER_QUERY_ROOM_INFO_REQ, QueryRoomInfoRequest) // 查询房间信息 16 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_MYSQL_INNER_QUERY_PLAYER_INFO_REQ, QueryPlayerInfoRequest) // 查询玩家信息 17 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_MYSQL_INNER_QUERY_GAME_INFO_REQ, QueryGameInfoRequest) // 查询游戏信息 18 | } 19 | -------------------------------------------------------------------------------- /src/mysqlsvr/globals/globals.go: -------------------------------------------------------------------------------- 1 | package globals 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/db/mysql" 5 | orm "github.com/Iori372552686/GoOne/lib/db/xorm" 6 | "github.com/Iori372552686/GoOne/lib/service/transaction" 7 | ) 8 | 9 | var TransMgr = transaction.NewTransactionMgr() 10 | var MysqlMgr = mysql.NewMysqlMgr() 11 | var OrmMgr = orm.NewOrmMgr() 12 | -------------------------------------------------------------------------------- /src/mysqlsvr/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | 6 | "github.com/Iori372552686/GoOne/lib/api/logger" 7 | "github.com/Iori372552686/GoOne/lib/service/application" 8 | ) 9 | 10 | func main() { 11 | flag.Parse() 12 | defer logger.Flush() 13 | 14 | application.Init(&MysqlSvrImpl{}) 15 | application.Run() 16 | } 17 | -------------------------------------------------------------------------------- /src/mysqlsvr/manager/table_mgr.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/service/async" 5 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 6 | ) 7 | 8 | const ( 9 | ASYNC_COUNT = 15 10 | ) 11 | 12 | var ( 13 | tables = []interface{}{} 14 | handlers = async.NewAsyncPool(ASYNC_COUNT) 15 | ) 16 | 17 | type IUpdate interface { 18 | GetUpdateTime() int64 19 | } 20 | 21 | func GetTables() []interface{} { 22 | return tables 23 | } 24 | 25 | func init() { 26 | // 启动协程 27 | for _, handler := range handlers { 28 | handler.Start() 29 | } 30 | 31 | // 注册mysql表 32 | tables = append(tables, 33 | new(g1_protocol.MysqlTexasRoomInfo), 34 | new(g1_protocol.MysqlTexasPlayerInfo), 35 | new(g1_protocol.MysqlTexasGameInfo), 36 | ) 37 | } 38 | 39 | func Push(id int64, f func()) { 40 | handlers[id%ASYNC_COUNT].Push(f) 41 | } 42 | 43 | func Close() { 44 | for _, handler := range handlers { 45 | handler.Stop() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/roomcentersvr/cmd_handler/adapter.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/cmd_handler" 5 | "github.com/Iori372552686/GoOne/src/roomcentersvr/globals" 6 | "github.com/Iori372552686/GoOne/src/roomcentersvr/room_mgr/texas_room" 7 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 8 | ) 9 | 10 | type AdapterZoneMgrFunc func(c cmd_handler.IContext, data []byte, roomMgr *texas_room.TexasRoomCenterMgr) g1_protocol.ErrorCode 11 | 12 | // logAdapter is a adapter for game log command 13 | type logAdapter struct { 14 | Cmd AdapterZoneMgrFunc 15 | } 16 | 17 | func NewZoneAdapter(rCmd AdapterZoneMgrFunc) cmd_handler.CmdHandlerFunc { 18 | a := new(logAdapter) 19 | a.Cmd = rCmd 20 | return a.ProcessCmd 21 | } 22 | 23 | func (impl *logAdapter) ProcessCmd(c cmd_handler.IContext, data []byte) g1_protocol.ErrorCode { 24 | ins := globals.RoomListMgr.GetRoomMgrObj(c.Rid()) 25 | if ins == nil { 26 | return g1_protocol.ErrorCode_ERR_ARGV 27 | } 28 | 29 | return impl.Cmd(c, data, ins) 30 | } 31 | -------------------------------------------------------------------------------- /src/roomcentersvr/cmd_handler/register.go: -------------------------------------------------------------------------------- 1 | package cmd_handler 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/Iori372552686/GoOne/src/roomcentersvr/globals" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | ) 8 | 9 | // 所有的命令字对应的go需要在这里先注册 10 | func RegCmd() { 11 | logger.Infof("register transaction commands") 12 | 13 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_ROOM_CENTER_INNER_ROOM_LIST_REQ, NewZoneAdapter(InnerGetRoomList)) 14 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_ROOM_CENTER_INNER_UPDATE_ROOM_INFO_REQ, NewZoneAdapter(InnerUpdateRoomInfo)) 15 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_ROOM_CENTER_INNER_DEL_ROOM_INFO_REQ, NewZoneAdapter(InnerDelRoomInfo)) 16 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_ROOM_CENTER_INNER_QUICK_START_REQ, NewZoneAdapter(InnerQuickStart)) 17 | 18 | //inner 19 | globals.TransMgr.RegisterCmd(g1_protocol.CMD_ROOM_CENTER_INNER_TICK_REQ, NewZoneAdapter(InnerTick)) 20 | } 21 | -------------------------------------------------------------------------------- /src/roomcentersvr/globals/globals.go: -------------------------------------------------------------------------------- 1 | package globals 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/service/transaction" 5 | "github.com/Iori372552686/GoOne/src/roomcentersvr/room_mgr" 6 | ) 7 | 8 | var TransMgr = transaction.NewTransactionMgr() 9 | var RoomListMgr = room_mgr.NewRoomMgr() 10 | -------------------------------------------------------------------------------- /src/roomcentersvr/globals/idgen/idgen.go: -------------------------------------------------------------------------------- 1 | package id 2 | 3 | import "github.com/Iori372552686/GoOne/lib/util/idgen" 4 | 5 | var IDGen *idgen.TIDGen 6 | -------------------------------------------------------------------------------- /src/roomcentersvr/logic/quick_start.go: -------------------------------------------------------------------------------- 1 | package logic 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/src/roomcentersvr/room_ai" 5 | "github.com/Iori372552686/GoOne/src/roomcentersvr/room_mgr/texas_room" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | ) 8 | 9 | func OnCenterQuickStart(req *g1_protocol.QuickStartReq, roomMgr *texas_room.TexasRoomCenterMgr) *g1_protocol.QuickStartRsp { 10 | rsp := &g1_protocol.QuickStartRsp{Ret: &g1_protocol.Ret{Code: g1_protocol.ErrorCode_ERR_OK}} 11 | 12 | texas := roomMgr.GetTexasObj(int32(req.Stage)) 13 | if texas.RoomsMap == nil { 14 | rsp.Ret.Code = g1_protocol.ErrorCode_ERR_NOT_EXIST_GAME_ROOM 15 | return rsp 16 | } 17 | 18 | for _, room := range texas.RoomsMap { 19 | if room.Base.MaxPlayer < room.Base.CurPlayerNum { 20 | room.Base.CurPlayerNum++ 21 | rsp.RoomInfo = room.Base 22 | 23 | texas.Save() 24 | return rsp 25 | } 26 | } 27 | 28 | // 如果没有空余的房间,创建一个新的房间 29 | base, err := room_ai.OnAiCreatRoom(req.GameId, int32(req.CoinType), int32(req.Stage)) 30 | if err != nil { 31 | rsp.Ret.Code = g1_protocol.ErrorCode_ERR_TEXAS_SEAT_NOT_FOUND 32 | } 33 | 34 | rsp.RoomInfo = base 35 | return rsp 36 | } 37 | -------------------------------------------------------------------------------- /src/roomcentersvr/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | 6 | "github.com/Iori372552686/GoOne/lib/api/logger" 7 | "github.com/Iori372552686/GoOne/lib/service/application" 8 | ) 9 | 10 | func main() { 11 | flag.Parse() 12 | defer logger.Flush() 13 | 14 | application.Init(&RoomMgrSvrImpl{}) 15 | application.Run() 16 | } 17 | -------------------------------------------------------------------------------- /src/roomcentersvr/room_mgr/data_proc.go: -------------------------------------------------------------------------------- 1 | package room_mgr 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/src/roomcentersvr/room_mgr/texas_room" 5 | ) 6 | 7 | // ----------------------------------------------public---------------------------------------------- 8 | func (impl *RoomMgr) GetRoomMgrObj(index uint64) *texas_room.TexasRoomCenterMgr { 9 | var data *texas_room.TexasRoomCenterMgr 10 | var has bool 11 | 12 | impl.RLock() 13 | if data, has = impl.TexasMgr[index]; !has { 14 | impl.RUnlock() 15 | impl.Lock() 16 | 17 | //map double-check 18 | if data, has = impl.TexasMgr[index]; !has { 19 | data = texas_room.NewTexasRoomCenterMgr(index) 20 | impl.TexasMgr[index] = data 21 | } 22 | 23 | impl.Unlock() 24 | } else { 25 | impl.RUnlock() 26 | } 27 | 28 | return data 29 | } 30 | -------------------------------------------------------------------------------- /src/roomcentersvr/room_mgr/texas_room/data_proc.go: -------------------------------------------------------------------------------- 1 | package texas_room 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/src/roomcentersvr/room_mgr/texas_room/texas" 5 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 6 | ) 7 | 8 | func (impl *TexasRoomCenterMgr) saveRoomDataToDB() error { 9 | for _, roomInfo := range impl.TexasMap { 10 | if roomInfo.CheckChange() { 11 | /* impl.InnerInsGuildTexasGameRoomDataSave(ctx, &pb.InsGuildTexasGameRoomDataSaveReq{ 12 | DataType: pb.TexasGameRoom_DATA_TYPE_game_data, 13 | roomId: GameData.roomId, SrvKey: frpc.GetLocalAddr(), 14 | }, "", GameData.roomId) 15 | */ 16 | //logger.Debugf("saveGameData gid:%v", GameData.Base.RoomId) 17 | } 18 | } 19 | 20 | return nil 21 | } 22 | 23 | // ----------------------------------------------public---------------------------------------------- 24 | func (impl *TexasRoomCenterMgr) GetTexasObj(stage int32) *texas.TexasRoom { 25 | var data *texas.TexasRoom 26 | var has bool 27 | 28 | impl.RLock() 29 | if data, has = impl.TexasMap[stage]; !has { 30 | impl.RUnlock() 31 | impl.Lock() 32 | 33 | //map double-check 34 | if data, has = impl.TexasMap[stage]; !has { 35 | data = texas.NewTexasRoomObj(impl.Index, stage) 36 | impl.TexasMap[stage] = data 37 | } 38 | 39 | impl.Unlock() 40 | } else { 41 | impl.RUnlock() 42 | } 43 | 44 | return data 45 | } 46 | 47 | func (impl *TexasRoomCenterMgr) SetTexasRoom(data *g1_protocol.DBTexasRoomCenterInfo) error { 48 | if data == nil { 49 | return nil 50 | } 51 | return impl.GetTexasObj(int32(data.Stage)).Set(data) 52 | } 53 | 54 | func (impl *TexasRoomCenterMgr) OnCleanData(Stage int32) error { 55 | if !impl.checkOpen() || Stage == 0 { 56 | return nil 57 | } 58 | 59 | impl.Lock() 60 | delete(impl.TexasMap, Stage) 61 | impl.Unlock() 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /src/roomcentersvr/room_mgr/texas_room/texas/base.go: -------------------------------------------------------------------------------- 1 | package texas 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/Iori372552686/GoOne/lib/api/datetime" 7 | pb "github.com/Iori372552686/game_protocol/protocol" 8 | ) 9 | 10 | type TexasRoom struct { 11 | *pb.DBTexasRoomCenterInfo //TexasRoomInfo pb 12 | 13 | //private 14 | upTime int64 15 | isChange bool 16 | } 17 | 18 | func NewTexasRoomObj(index uint64, stage int32) *TexasRoom { 19 | ins := &TexasRoom{} 20 | ins.init(index, stage) 21 | return ins 22 | } 23 | 24 | func (impl *TexasRoom) init(index uint64, stage int32) { 25 | impl.DBTexasRoomCenterInfo = &pb.DBTexasRoomCenterInfo{ 26 | Index: index, 27 | Stage: pb.RoomStage(stage), 28 | RoomsMap: make(map[uint64]*pb.RoomShowInfo), 29 | } 30 | } 31 | 32 | func (impl *TexasRoom) Get() *pb.DBTexasRoomCenterInfo { 33 | return impl.DBTexasRoomCenterInfo 34 | } 35 | 36 | func (impl *TexasRoom) Save() { 37 | impl.isChange = true 38 | } 39 | 40 | func (impl *TexasRoom) CheckChange() bool { 41 | return impl.isChange 42 | } 43 | 44 | func (impl *TexasRoom) Update() (err error) { 45 | data := impl.Get() 46 | if data == nil { 47 | return 48 | } 49 | 50 | //err = global.GlobalDB.SetDBGuildInstanceData(ctx, data) 51 | if err != nil { 52 | return 53 | } 54 | 55 | impl.isChange = false 56 | return 57 | } 58 | 59 | func (impl *TexasRoom) Set(data *pb.DBTexasRoomCenterInfo) error { 60 | if impl == nil || data == nil { 61 | return errors.New("param error") 62 | } 63 | 64 | impl.DBTexasRoomCenterInfo = data 65 | impl.upTime = datetime.NowMs() 66 | impl.isChange = true 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /tools/cfgtool/domain/define.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | const ( 4 | // 类类型 5 | TypeOfConfig = 4 6 | TypeOfStruct = 3 7 | TypeOfEnum = 2 8 | TypeOfBase = 1 9 | 10 | // 值类型 11 | ValueOfBase = 1 12 | ValueOfList = 2 13 | ValueOfMap = 3 14 | ValueOfGroup = 4 15 | ) 16 | 17 | var ( 18 | Module = "" // 项目目录 19 | ProtoPkgName = "g1.protocol" // proto包名 20 | PkgName = "" // 包名 21 | XlsxPath = "" // 解析文件路径 22 | ProtoPath = "" // proto文件路径 23 | PbPath = "" // proto生成路径 24 | CodePath = "" // 代码生成路径 25 | JsonPath = "" // 数据文件路径 26 | BytesPath = "" // 数据文件路径 27 | TextPath = "" // 数据文件路径 28 | ) 29 | -------------------------------------------------------------------------------- /tools/cfgtool/internal/base/typespec.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type Type struct { 4 | Name string 5 | TypeOf int 6 | ValueOf int 7 | } 8 | 9 | type Convert struct { 10 | Name string // 装换类型 11 | ConvFunc func(string) interface{} // 装换函数 12 | } 13 | 14 | type Field struct { 15 | Type *Type 16 | Name string 17 | Desc string 18 | Position int 19 | ConvFunc func(string) interface{} // 装换函数 20 | } 21 | 22 | type Struct struct { 23 | Name string // 结构体名称 24 | Fields map[string]*Field // 字段类型 25 | FieldList []*Field // 字段类型 26 | Converts map[string][]*Field // 转换表 27 | Sheet string 28 | FileName string // 文件名 29 | } 30 | 31 | type Index struct { 32 | Type *Type // 成员变量类型 33 | Name string // 成员变量 34 | List []*Field // 类型字段 35 | } 36 | 37 | type Config struct { 38 | Name string 39 | Fields map[string]*Field 40 | FieldList []*Field 41 | Indexs map[int][]*Index 42 | IndexList []*Index 43 | Sheet string 44 | FileName string 45 | } 46 | 47 | type EValue struct { 48 | Name string // 枚举值名称 49 | Value int32 // 枚举值 50 | Desc string // 枚举值描述 51 | } 52 | 53 | type Enum struct { 54 | Name string 55 | Values map[string]*EValue 56 | ValueList []*EValue 57 | Sheet string 58 | FileName string 59 | } 60 | 61 | type Table struct { 62 | TypeOf int 63 | Sheet string 64 | Type string 65 | FileName string 66 | Rules []string 67 | Rows [][]string 68 | } 69 | -------------------------------------------------------------------------------- /tools/cfgtool/internal/manager/table_mgr.go: -------------------------------------------------------------------------------- 1 | package manager 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/Iori372552686/GoOne/tools/cfgtool/domain" 7 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/base" 8 | ) 9 | 10 | var ( 11 | tableMgr = make(map[string]*base.Table) 12 | groupMgr = make(map[int][]*base.Table) 13 | ) 14 | 15 | func AddTable(file, sheet string, typeOf int, t string, rows [][]string, rules []string) { 16 | key := file + ":" + sheet 17 | val := &base.Table{ 18 | Type: t, 19 | TypeOf: typeOf, 20 | Sheet: sheet, 21 | FileName: file, 22 | Rules: rules, 23 | Rows: rows, 24 | } 25 | tableMgr[key] = val 26 | groupMgr[val.TypeOf] = append(groupMgr[val.TypeOf], val) 27 | } 28 | 29 | func GetTable(file, sheet string) *base.Table { 30 | return tableMgr[file+":"+sheet] 31 | } 32 | 33 | func GetTableList(typeOf int) []*base.Table { 34 | return groupMgr[typeOf] 35 | } 36 | 37 | func GetTypeOf(name string) int { 38 | name = GetConvType(name) 39 | if _, ok := enumMgr[name]; ok { 40 | return domain.TypeOfEnum 41 | } 42 | if _, ok := structMgr[name]; ok { 43 | return domain.TypeOfStruct 44 | } 45 | return domain.TypeOfBase 46 | } 47 | 48 | func GetValueOf(name string) int { 49 | if strings.HasPrefix(name, "[]") { 50 | return domain.ValueOfList 51 | } 52 | return domain.ValueOfBase 53 | } 54 | -------------------------------------------------------------------------------- /tools/cfgtool/internal/parser/reference.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/tools/cfgtool/domain" 5 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/manager" 6 | ) 7 | 8 | func parseReference() { 9 | for _, item := range manager.GetStructMap() { 10 | tmps := map[string]struct{}{} 11 | for _, field := range item.FieldList { 12 | switch field.Type.TypeOf { 13 | case domain.TypeOfEnum: 14 | en := manager.GetEnum(field.Type.Name) 15 | if en.FileName != item.FileName { 16 | tmps[en.FileName] = struct{}{} 17 | } 18 | case domain.TypeOfStruct: 19 | st := manager.GetStruct(field.Type.Name) 20 | if st.FileName != item.FileName { 21 | tmps[st.FileName] = struct{}{} 22 | } 23 | case domain.TypeOfConfig: 24 | cfg := manager.GetConfig(field.Type.Name) 25 | if cfg.FileName != item.FileName { 26 | tmps[cfg.FileName] = struct{}{} 27 | } 28 | } 29 | } 30 | manager.AddRef(item.FileName, tmps) 31 | } 32 | 33 | for _, item := range manager.GetConfigMap() { 34 | tmps := map[string]struct{}{} 35 | for _, field := range item.FieldList { 36 | switch field.Type.TypeOf { 37 | case domain.TypeOfEnum: 38 | en := manager.GetEnum(field.Type.Name) 39 | if en.FileName != item.FileName { 40 | tmps[en.FileName] = struct{}{} 41 | } 42 | case domain.TypeOfStruct: 43 | st := manager.GetStruct(field.Type.Name) 44 | if st.FileName != item.FileName { 45 | tmps[st.FileName] = struct{}{} 46 | } 47 | case domain.TypeOfConfig: 48 | cfg := manager.GetConfig(field.Type.Name) 49 | if cfg.FileName != item.FileName { 50 | tmps[cfg.FileName] = struct{}{} 51 | } 52 | } 53 | } 54 | manager.AddRef(item.FileName, tmps) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tools/cfgtool/internal/templ/index_tpl.go: -------------------------------------------------------------------------------- 1 | package templ 2 | 3 | const indexTpl = ` 4 | /* 5 | * 本代码由xlsx工具生成,请勿手动修改 6 | */ 7 | 8 | package {{.Pkg}} 9 | 10 | {{define "member" -}} 11 | {{- if gt . 0 -}} 12 | T{{.}} T{{.}} 13 | {{template "member" sub . 1}} 14 | {{- end -}} 15 | {{- end -}} 16 | 17 | {{- define "type" -}} 18 | {{- if gt . 0 -}} T{{.}} {{- if gt . 1 -}},{{- end -}} {{template "type" sub . 1}} {{- end -}} 19 | {{- end -}} 20 | 21 | {{range $pos := .IndexList -}} 22 | {{if gt $pos 1 -}} 23 | type Index{{$pos}}[{{template "type" $pos}} any] struct { 24 | {{template "member" $pos}} 25 | } 26 | {{- end}} 27 | {{- end}} 28 | ` 29 | -------------------------------------------------------------------------------- /tools/cfgtool/service/code_gen.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "bytes" 5 | "path" 6 | 7 | "strings" 8 | 9 | "github.com/Iori372552686/GoOne/tools/cfgtool/domain" 10 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/base" 11 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/manager" 12 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/templ" 13 | "github.com/iancoleman/strcase" 14 | ) 15 | 16 | type ConfigInfo struct { 17 | PbPkg string 18 | Pkg string 19 | *base.Config 20 | } 21 | 22 | type IndexInfo struct { 23 | Pkg string 24 | IndexList []int 25 | } 26 | 27 | func GenCode(buf *bytes.Buffer) error { 28 | if len(domain.PbPath) <= 0 || len(domain.CodePath) <= 0 || len(domain.Module) <= 0 { 29 | return nil 30 | } 31 | 32 | // 生成索引 33 | if err := genIndex(buf); err != nil { 34 | return err 35 | } 36 | // 对文件分类 37 | for _, st := range manager.GetConfigMap() { 38 | buf.Reset() 39 | dataName := strings.TrimSuffix(st.Name, "Config") 40 | name := strcase.ToSnake(st.Name) 41 | item := &ConfigInfo{ 42 | PbPkg: domain.PkgName, 43 | Pkg: name, 44 | Config: st, 45 | } 46 | if err := templ.CodeTpl.Execute(buf, item); err != nil { 47 | return err 48 | } 49 | // 保存代码 50 | if err := base.SaveGo(path.Join(domain.CodePath, name), dataName+"Data.gen.go", buf.Bytes()); err != nil { 51 | return err 52 | } 53 | } 54 | return nil 55 | } 56 | -------------------------------------------------------------------------------- /tools/cfgtool/service/index_gen.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "bytes" 5 | "github.com/Iori372552686/GoOne/lib/api/uerror" 6 | 7 | "sort" 8 | 9 | "github.com/Iori372552686/GoOne/tools/cfgtool/domain" 10 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/base" 11 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/manager" 12 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/templ" 13 | ) 14 | 15 | func genIndex(buf *bytes.Buffer) error { 16 | indexs := &IndexInfo{ 17 | Pkg: "g1_protocol", 18 | IndexList: manager.GetIndexMap(), 19 | } 20 | 21 | if len(indexs.IndexList) > 0 { 22 | sort.Slice(indexs.IndexList, func(i, j int) bool { 23 | return indexs.IndexList[i] < indexs.IndexList[j] 24 | }) 25 | 26 | buf.Reset() 27 | if err := templ.IndexTpl.Execute(buf, indexs); err != nil { 28 | return uerror.New(1, -1, "gen index file error: %s", err.Error()) 29 | } 30 | return base.SaveGo(domain.ProtoPath, "index.gen.go", buf.Bytes()) 31 | } 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /tools/cfgtool/test/tool_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "path/filepath" 8 | 9 | "github.com/Iori372552686/GoOne/tools/cfgtool/domain" 10 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/base" 11 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/manager" 12 | "github.com/Iori372552686/GoOne/tools/cfgtool/internal/parser" 13 | "github.com/Iori372552686/GoOne/tools/cfgtool/service" 14 | ) 15 | 16 | func TestConfig(t *testing.T) { 17 | domain.XlsxPath = "../../../../poker_gameconf" 18 | domain.TextPath = "../gen/data" 19 | domain.ProtoPath = "../gen/proto" 20 | domain.CodePath = "../gen/code" 21 | domain.Module = "github.com/Iori372552686/GoOne" 22 | domain.PbPath = "github.com/Iori372552686/game_protocol/protocol" 23 | domain.PkgName = filepath.Base(domain.PbPath) 24 | 25 | // 加载所有配置 26 | files, err := base.Glob(domain.XlsxPath, ".*\\.xlsx", true) 27 | if err != nil { 28 | panic(err) 29 | } 30 | // 解析所有文件 31 | if err := parser.ParseFiles(files...); err != nil { 32 | panic(err) 33 | } 34 | // 生成proto文件数据 35 | buf := bytes.NewBuffer(nil) 36 | if err := service.GenProto(buf); err != nil { 37 | panic(err) 38 | } 39 | if err := service.SaveProto(); err != nil { 40 | panic(err) 41 | } 42 | // 解析proto文件 43 | if err := manager.ParseProto(); err != nil { 44 | panic(err) 45 | } 46 | if err := service.GenData(); err != nil { 47 | panic(err) 48 | } 49 | if err := service.GenCode(buf); err != nil { 50 | panic(err) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tools/tester/conn_test.go: -------------------------------------------------------------------------------- 1 | package tester 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/sharedstruct" 5 | "github.com/Iori372552686/GoOne/tools/tester/tester_util" 6 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 7 | "github.com/golang/protobuf/proto" 8 | "testing" 9 | ) 10 | 11 | func TestConn(t *testing.T) { 12 | s := tester_util.NewSession(t) 13 | err := s.Open() 14 | if err != nil { 15 | return 16 | } 17 | defer s.Close() 18 | body := &g1_protocol.LoginReq{ 19 | Account: "test", 20 | Token: "ykocG0rfZkgWDY07i8%2FiKdlKCrU5x0T07BinE%2FIRPpSG0R4JsvwpjnM7TYOHIhBlaWk%2BQnBj%2FMbNdUETZJVwU8nIRRfWkTO%2Bcdek4lc8HpLYMGjTUpBG4l2vA3Gkw9KoRp7DCF3ViOCgvR9t%2FFySQs54JGKhnDItWNdlcNKeVX0a6EmqR1Zm%2FmrswYgLGqrf", 21 | ChannelId: 1, 22 | LoginType: "guest", 23 | DeviceOs: "web", 24 | } 25 | 26 | bodyBytes, err := proto.Marshal(body) 27 | 28 | header := sharedstruct.CSPacketHeader{ 29 | Version: 1, 30 | PassCode: 1, 31 | Seq: 1, 32 | Uid: 0, 33 | Cmd: uint32(g1_protocol.CMD_MAIN_LOGIN_REQ), 34 | BodyLen: uint32(len(bodyBytes)), 35 | } 36 | s.Send(header.ToBytes()) 37 | s.Send(bodyBytes) 38 | } 39 | -------------------------------------------------------------------------------- /tools/tester/login_test.go: -------------------------------------------------------------------------------- 1 | package tester 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/tools/tester/tester_util" 5 | "testing" 6 | ) 7 | 8 | func TestLogin(t *testing.T) { 9 | s := tester_util.NewSession(t) 10 | err := s.OpenAndLogin() 11 | if err != nil { 12 | return 13 | } 14 | defer s.LogoutAndClose() 15 | } 16 | -------------------------------------------------------------------------------- /tools/tester/sync_data_test.go: -------------------------------------------------------------------------------- 1 | package tester 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/tools/tester/tester_util" 5 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 6 | "testing" 7 | ) 8 | 9 | func TestSyncClientData(t *testing.T) { 10 | s := tester_util.NewSession(t) 11 | err := s.OpenAndLogin() 12 | if err != nil { 13 | return 14 | } 15 | defer s.LogoutAndClose() 16 | 17 | req := &g1_protocol.MallBuyPackageReq{ 18 | ConfId: 8, 19 | } 20 | err = s.SendCmd(uint32(g1_protocol.CMD_MAIN_MALL_BUY_PACKAGE_REQ), req) 21 | if err != nil { 22 | return 23 | } 24 | 25 | msg := &g1_protocol.ScSyncUserData{} 26 | err = s.WaitTillCmd(uint32(g1_protocol.CMD_SC_SYNC_USER_DATA), msg) 27 | if err != nil { 28 | return 29 | } 30 | 31 | //rsp := &g1_protocol.BuyRsp{} 32 | //err = s.WaitTillCmd(uint32(g1_protocol.CMD_MAIN_BUY_RSP), rsp) 33 | //if err != nil { 34 | // return 35 | //} 36 | } 37 | -------------------------------------------------------------------------------- /tools/tester/t_test.go: -------------------------------------------------------------------------------- 1 | package tester 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func fn1(t *testing.T) { 10 | timer := time.NewTimer(3 * time.Second) 11 | defer timer.Stop() 12 | for { 13 | select { 14 | case <- timer.C: 15 | break 16 | } 17 | fmt.Println("aaaa") 18 | break 19 | } 20 | fmt.Println("bbb") 21 | } 22 | 23 | func fn2(t *testing.T) { 24 | fmt.Println("a") 25 | if true { 26 | defer fmt.Println("b") 27 | } 28 | fmt.Println("c") 29 | } 30 | 31 | func fn3() { 32 | for _ = range "12" { 33 | fmt.Println("a") 34 | } 35 | } 36 | 37 | func TestT(t *testing.T) { 38 | fn3() 39 | } 40 | -------------------------------------------------------------------------------- /tools/tester/tester_util/role.go: -------------------------------------------------------------------------------- 1 | package tester_util 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Iori372552686/GoOne/lib/api/datetime" 6 | "github.com/Iori372552686/GoOne/lib/api/sharedstruct" 7 | g1_protocol "github.com/Iori372552686/game_protocol/protocol" 8 | "github.com/golang/protobuf/proto" 9 | ) 10 | 11 | type Role struct { 12 | uid uint64 13 | } 14 | 15 | func (r *Role) SetUid(uid uint64) { 16 | r.uid = uid 17 | } 18 | 19 | func (r *Role) GetUid() uint64 { 20 | return r.uid 21 | } 22 | 23 | func (r *Role) Getlogin() ([]byte, error) { 24 | body := &g1_protocol.LoginReq{ 25 | Account: "test", 26 | Token: "ykocG0rfZkgWDY07i8%2FiKdlKCrU5x0T07BinE%2FIRPpSG0R4JsvwpjnM7TYOHIhBlaWk%2BQnBj%2FMbNdUETZJVwU8nIRRfWkTO%2Bcdek4lc8HpLYMGjTUpBG4l2vA3Gkw9KoRp7DCF3ViOCgvR9t%2FFySQs54JGKhnDItWNdlcNKeVX0a6EmqR1Zm%2FmrswYgLGqrf", 27 | ChannelId: 1, 28 | LoginType: "guest", //游客登陆 29 | DeviceOs: "web", 30 | } 31 | 32 | bodyBytes, err := proto.Marshal(body) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | header := sharedstruct.CSPacketHeader{ 38 | Version: 1, 39 | PassCode: 1, 40 | Seq: 1, 41 | Uid: 0, 42 | Cmd: uint32(g1_protocol.CMD_MAIN_LOGIN_REQ), 43 | BodyLen: uint32(len(bodyBytes)), 44 | } 45 | 46 | return append(header.ToBytes(), bodyBytes...), nil 47 | } 48 | 49 | func (r *Role) GetHeartbeat(uid uint64) ([]byte, error) { 50 | timeMs := datetime.NowMs() 51 | body := &g1_protocol.HeartBeatReq{ 52 | ClientNowMs: timeMs, 53 | } 54 | bodyBytes, err := proto.Marshal(body) 55 | 56 | if err != nil { 57 | fmt.Printf("heartBeat Marshal error: %v", err) 58 | return nil, err 59 | } 60 | 61 | header := sharedstruct.CSPacketHeader{ 62 | Version: 1, 63 | PassCode: 1, 64 | Seq: 1, 65 | Uid: uid, 66 | Cmd: uint32(g1_protocol.CMD_MAIN_HEARTBEAT_REQ), 67 | BodyLen: uint32(len(bodyBytes)), 68 | } 69 | return append(header.ToBytes(), bodyBytes...), nil 70 | } 71 | -------------------------------------------------------------------------------- /tools/tester/tester_util/tester_util.go: -------------------------------------------------------------------------------- 1 | package tester_util 2 | 3 | import ( 4 | "github.com/Iori372552686/GoOne/lib/api/logger" 5 | "github.com/Iori372552686/GoOne/lib/api/sharedstruct" 6 | "github.com/golang/protobuf/proto" 7 | "io" 8 | "net" 9 | ) 10 | 11 | //todo: 不应该有uid 12 | func SendCmd(conn net.Conn, uid uint64, cmd uint32, req proto.Message) error { 13 | out, err := proto.Marshal(req) 14 | if err != nil { 15 | return err 16 | } 17 | 18 | // header 19 | header := sharedstruct.CSPacketHeader{} 20 | header.Uid = uid 21 | header.Cmd = cmd 22 | header.BodyLen = uint32(len(out)) 23 | conn.Write(header.ToBytes()) 24 | // body 25 | conn.Write(out) 26 | 27 | return nil 28 | } 29 | 30 | func WaitTillCmd(conn net.Conn, cmd uint32, rsp proto.Message) error { 31 | header := sharedstruct.CSPacketHeader{} 32 | headerBuf := make([]byte, sharedstruct.ByteLenOfCSPacketHeader()) 33 | readBuf := [1024]byte{} 34 | 35 | for header.Cmd != cmd { 36 | _, err := io.ReadFull(conn, headerBuf) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | header.From(headerBuf) 42 | 43 | body := readBuf[:header.BodyLen] 44 | _, err = io.ReadFull(conn, body) 45 | if err != nil { 46 | return err 47 | } 48 | 49 | logger.Debugf("received: %#v", header) 50 | 51 | if header.Cmd == cmd { 52 | err = proto.Unmarshal(readBuf[:header.BodyLen], rsp) 53 | if err != nil { 54 | return err 55 | } 56 | } 57 | } 58 | 59 | return nil 60 | } 61 | --------------------------------------------------------------------------------