#include #include #include #include #include #include #include #include #include #include "framework/cpp/utils.h" namespace f8 { bool ReadCsvMetaFile(const std::string& filename, google::protobuf::Message* prototype, std::function push_back_func) { const google::protobuf::Descriptor* descriptor = prototype->GetDescriptor(); const google::protobuf::Reflection* reflection = prototype->GetReflection(); a8::CsvReader reader; reader.Load(filename); while (reader.NextLine()) { google::protobuf::Message* msg = prototype->New(); for (int i = 0; i < descriptor->field_count(); ++i) { const google::protobuf::FieldDescriptor* field_desc = descriptor->field(i); const std::string& field_name = field_desc->name(); if (field_name.empty() || field_name[0] == '_') { continue; } if (!reader.KeyExists(field_name) && field_desc->is_optional()) { continue; } switch (field_desc->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { reflection->SetString(msg, field_desc, reader.GetValue(field_name)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { reflection->SetInt32(msg, field_desc, reader.GetValue(field_name)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { reflection->SetUInt32(msg, field_desc, reader.GetValue(field_name)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { reflection->SetInt64(msg, field_desc, reader.GetValue(field_name)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { reflection->SetUInt64(msg, field_desc, reader.GetValue(field_name)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { reflection->SetFloat(msg, field_desc, (double)reader.GetValue(field_name)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { reflection->SetDouble(msg, field_desc, reader.GetValue(field_name)); } break; default: { abort(); } break; }//end switch }//end for push_back_func(msg); delete msg; } return true; } static bool JsonToMessage(a8::XObject& jsonobj, google::protobuf::Message* msg) { const google::protobuf::Descriptor* descriptor = msg->GetDescriptor(); const google::protobuf::Reflection* reflection = msg->GetReflection(); for (int i = 0; i < descriptor->field_count(); ++i) { const google::protobuf::FieldDescriptor* field_desc = descriptor->field(i); const std::string& field_name = field_desc->name(); if (field_name.empty() || field_name[0] == '_') { continue; } if (!jsonobj.HasKey(field_name) && field_desc->is_optional()) { continue; } if (field_desc->is_repeated()) { std::shared_ptr repeated_field = jsonobj.At(field_name); if (!repeated_field) { continue; } for (int i = 0; i < repeated_field->Size(); ++i) { auto field_value = repeated_field->At(i); switch (field_desc->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { reflection->AddString(msg, field_desc, field_value->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { reflection->AddInt32(msg, field_desc, field_value->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { reflection->AddUInt32(msg, field_desc, field_value->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { reflection->AddInt64(msg, field_desc, field_value->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { reflection->AddUInt64(msg, field_desc, field_value->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { reflection->AddFloat(msg, field_desc, (double)field_value->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { reflection->AddDouble(msg, field_desc, field_value->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { google::protobuf::Message* p = reflection->AddMessage(msg, field_desc); JsonToMessage(*field_value, p); } break; default: { abort(); } break; }//end switch } } else { switch (field_desc->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { reflection->SetString(msg, field_desc, jsonobj.At(field_name)->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { reflection->SetInt32(msg, field_desc, jsonobj.At(field_name)->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { reflection->SetUInt32(msg, field_desc, jsonobj.At(field_name)->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { reflection->SetInt64(msg, field_desc, jsonobj.At(field_name)->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { reflection->SetUInt64(msg, field_desc, jsonobj.At(field_name)->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { reflection->SetFloat(msg, field_desc, (double)jsonobj.At(field_name)->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { reflection->SetDouble(msg, field_desc, jsonobj.At(field_name)->AsXValue()); } break; case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { google::protobuf::Message* p = reflection->MutableMessage(msg, field_desc); JsonToMessage(*jsonobj.At(field_name), p); } break; default: { abort(); } break; }//end switch } } return true; } static bool MessageToJson(const google::protobuf::Message* msg, a8::MutableXObject& jsonobj) { const google::protobuf::Descriptor* descriptor = msg->GetDescriptor(); const google::protobuf::Reflection* reflection = msg->GetReflection(); for (int i = 0; i < descriptor->field_count(); ++i) { const google::protobuf::FieldDescriptor* field_desc = descriptor->field(i); const std::string& field_name = field_desc->name(); if (field_desc->is_repeated()) { a8::MutableXObject* array_obj = a8::MutableXObject::NewArray(); std::shared_ptr repeated_field = jsonobj.At(field_name); continue; for (int i = 0; i < reflection->FieldSize(*msg, field_desc); ++i) { switch (field_desc->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { array_obj->Push(reflection->GetRepeatedBool(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { array_obj->Push(reflection->GetRepeatedString(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { array_obj->Push(reflection->GetRepeatedInt32(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { array_obj->Push(reflection->GetRepeatedUInt32(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { array_obj->Push(reflection->GetRepeatedInt64(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { array_obj->Push(reflection->GetRepeatedUInt64(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { array_obj->Push(reflection->GetRepeatedFloat(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { array_obj->Push(reflection->GetRepeatedDouble(*msg, field_desc, i)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { a8::MutableXObject* p = a8::MutableXObject::NewObject(); MessageToJson(&reflection->GetRepeatedMessage(*msg, field_desc, i), *p ); array_obj->Push(*p); delete p; } break; default: { abort(); } break; }//end switch } jsonobj.SetVal(field_name, *array_obj); delete array_obj; } else { switch (field_desc->cpp_type()) { case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { jsonobj.SetVal(field_name, reflection->GetBool(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { jsonobj.SetVal(field_name, reflection->GetString(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { jsonobj.SetVal(field_name, reflection->GetInt32(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { jsonobj.SetVal(field_name, reflection->GetUInt32(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { jsonobj.SetVal(field_name, reflection->GetInt64(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { jsonobj.SetVal(field_name, reflection->GetUInt64(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { jsonobj.SetVal(field_name, reflection->GetFloat(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { jsonobj.SetVal(field_name, reflection->GetDouble(*msg, field_desc)); } break; case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { a8::MutableXObject* p = a8::MutableXObject::NewObject(); MessageToJson(&reflection->GetMessage(*msg, field_desc), *p ); jsonobj.SetVal(field_name, *p); } break; default: { abort(); } break; }//end switch } } return true; } bool ReadJsonMetaFile(const std::string& filename, google::protobuf::Message* prototype, std::function push_back_func) { a8::XObject json_reader; json_reader.ReadFromJsonFile(filename); for (int i = 0; i < json_reader.Size(); ++i) { std::shared_ptr p = json_reader.At(i); google::protobuf::Message* msg = prototype->New(); JsonToMessage(*p, msg); push_back_func(msg); delete msg; } return true; } std::string PbToJson(const google::protobuf::Message* msg) { std::string data; a8::MutableXObject* p = a8::MutableXObject::NewObject(); MessageToJson(msg, *p); p->ToJsonStr(data); delete p; return data; } void InitMysqlConnection(a8::mysql::Query* query) { a8::UdpLog::Instance()->Info("show variables like 'character%';", {}); a8::UdpLog::Instance()->Info("Variable_name\tValue", {}); #if 1 query->ExecScript("SET character_set_server=utf8;", {}); query->ExecScript("SET NAMES utf8;", {}); #endif query->ExecQuery("show variables like 'character%';", {}); while (!query->Eof()) { std::string line; line = query->GetValue(0).GetString() + "\t" + query->GetValue(1).GetString(); a8::UdpLog::Instance()->Info(line.c_str(), {}); assert(!(query->GetValue(0).GetString() == "character_set_client" && query->GetValue(1).GetString() != "utf8")); assert(!(query->GetValue(0).GetString() == "character_set_connection" && query->GetValue(1).GetString() != "utf8")); assert(!(query->GetValue(0).GetString() == "character_set_database" && query->GetValue(1).GetString() != "utf8")); assert(!(query->GetValue(0).GetString() == "character_set_results" && query->GetValue(1).GetString() != "utf8")); assert(!(query->GetValue(0).GetString() == "character_set_server" && query->GetValue(1).GetString() != "utf8")); assert(!(query->GetValue(0).GetString() == "character_set_system" && query->GetValue(1).GetString() != "utf8")); query->Next(); } a8::UdpLog::Instance()->Info("show variables like '%collation%';", {}); a8::UdpLog::Instance()->Info("Variable_name\tValue", {}); query->ExecQuery("show variables like '%collation%';", {}); while (!query->Eof()) { std::string line; line = query->GetValue(0).GetString() + "\t" + query->GetValue(1).GetString(); a8::UdpLog::Instance()->Info(line.c_str(), {}); assert(query->GetValue(1).GetString() == "utf8_general_ci"); query->Next(); } } void CheckMysqlConnection(a8::mysql::Connection* conn, a8::mysql::Query* query, std::string dbhost, int port, std::string dbuser, std::string dbpasswd, std::string gamedb) { if (query->ExecQuery("SELECT 1;", {}) <= 0) { a8::UdpLog::Instance()->Warning("mysql disconnect", {}); if (conn->Connect(dbhost, 3306, dbuser, dbpasswd, gamedb)) { f8::InitMysqlConnection(query); a8::UdpLog::Instance()->Info("mysql reconnect successed", {}); } else { a8::UdpLog::Instance()->Info("mysql reconnect failed", {}); } } } bool CheckRegisterTimeInSessionId(const std::string& accountid, const std::string& sessionid) { std::vector strings; a8::Split(sessionid, strings, '_'); if (strings.size() < 4) { return false; } return true; } time_t ExtractRegisterTimeFromSessionId(const std::string& sessionid) { std::vector strings; a8::Split(sessionid, strings, '_'); if (strings.size() < 4) { return 0; } std::string session_createtime = strings[0]; std::string account_registertime = strings[1]; std::string md51 = strings[2]; std::string md52 = strings[3]; return a8::XValue(account_registertime); } bool IsValidSessionId(const std::string& accountid, const std::string& sessionid) { std::vector strings; a8::Split(sessionid, strings, '_'); if (strings.size() < 4) { return false; } return true; } bool LoginCheck(const std::string& accountid, const std::string& sessionid) { std::vector strings; a8::Split(sessionid, strings, '_'); if (strings.size() < 4) { return false; } if (IsOnlineEnv()) { //session_createtime account_registertime md51 md52 std::string md5_str = accountid + "f3a6a9a5-217a-4079-ab99-b5d69b8212be" + strings[1] + strings[0]; return a8::openssl::md5(md5_str) == strings[2]; } return true; } int ExtractGameIdFromAccountId(const std::string& accountid) { std::vector strings; a8::Split(accountid, strings, '_'); if (strings.size() < 2) { return false; } std::string channelid = strings[0]; std::string gameid = strings[1]; return a8::XValue(gameid); } int ExtractChannelIdFromAccountId(const std::string& accountid) { std::vector strings; a8::Split(accountid, strings, '_'); if (strings.size() < 2) { return false; } std::string channelid = strings[0]; std::string gameid = strings[1]; return a8::XValue(channelid); } bool IsOnlineEnv() { static bool is_online = !getenv("SERVER_ENV"); return is_online; } bool IsTestEnv() { static bool is_test = a8::SafeStrCmp(getenv("SERVER_ENV"), "TEST") == 0; return is_test; } bool IsValidNormalConfig(a8::XObject& conf, std::vector fields) { if (conf.GetType() != a8::XOT_ARRAY) { abort(); } for (int i = 0; i < conf.Size(); ++i) { std::shared_ptr node = conf.At(i); if (node->At("instance_id")->AsXValue().GetInt() != i + 1) { abort(); } for (std::string& field_name : fields) { if (!node->HasKey(field_name)) { abort(); } } } return true; } }