Решил я тут текстовую MMORPG на C++ написать
Итак, я вас сюда заманил, НО сразу повторю, это не гайд по созданию MMORPG на C++. Это нечто вроде моего дневника, куда я буду скидывать процесс разработки (Да, проект ещё не завершён, даже не близко, скорее только начат…). Почему я вообще тогда создал эту статью? Ну, коли ты крутой true-программист, буду рад советам, критике, помощи, ругани, проще говоря всему, что может помочь мне улучшить это. С другой стороны, если ты сам захотел создать нечто похожее, то, быть может, сможешь избежать всех трудностей, с которыми столкнулся я. И для первой, и для второй цели (и для того, чтобы сделать вид хоть сколько-то проделанной работы), я постараюсь как можно доступнее разжевывать всё, что делаю, так начнём же!
Начало
С чего начинается любой проект? С идеи и плана конечно! Идею я, пожалуй, поясню по ходу изложения, в любом случае она будет меняться… План же я нарисовал в виде схемки:
Вам страшно? У вас болят глаза? Вы желаете мне удачи (или гореть в аду) и покидаете эту статью? Ваша реакция оправдана, но я всё же не имею совести пояснить, что здесь, да как.
БД — это база данных, что будет хранить всю информацию по проекту, к ней мы вернёмся, но надолго не остановимся.
Админка — это некая панель управления миром, на ней будут создаваться новые объекты и размещаться в мире, а также писаться необходимые скрипты.
Мировой сервер — это сервер, что будет управлять автоматическими изменениями в мире, к примеру (просто пример, далеко не факт, что так и будет): горит огонь и со временем, соседние клетки начинают загораться, вот как-раз подобными процессами и будет управлять мировой сервер (не готов, но уже начат).
Клиентский менеджер (или менеджер клиентов) будет отвечать за работу с игроками, через него игроки будут как авторизироваться, так и получать необходимую клиенту информацию.
Чат будет встроен в клиентский менеджер (поэтому в зелёном кружочке), модерация чата также будет через него.
Клиенты — это уже приложения, через которые в теории будут играть пользователи, на их долю остаётся только то, как будет интерпретироваться, полученная от менеджера, информация.
БД
БД? БД! Но БД же? БД, БД, БД!!! Ох, ok. СУБД=MySQL, почему?
Куча документации.
Лёгкость установки и настройки
Нет проблем с лицензией!
Как установить MySQL на Windows: пошаговая инструкция | Timeweb Cloud
Коли вы осилили скачать и установить VS (или на чём вы там пишете), то проблем с установкой и настройкой MySQL быть не должно. Единственное укажу, что выбрал на данный момент я локальный сервер, ибо один!
И всё же я новичок в работе с MySQL, трудности у меня возникли с присоединением его к моему проекту C++. Впрочем, не так много, ибо документация на любой вкус и цвет решает). А начал я на VS, но мне показалось слишком муторно копаться в его настройках, потому я решил перенести весь процесс компоновки на CMake (да и вообще на VS Code перешёл зачем-то), и-и-и вот, что у меня получилось:
В папке MySQL Server 8.0 (по умолчанию устанавливается по пути: «C:\Program Files\MySQL\MySQL Server 8.0») нашёл папки include и lib. В папку с проектом копировал папку include, а из папки lib туда же копировал libmysql.lib и libmysql.dll (Изначально я с чего-то решил, что эти файлы будут в компоновщике SQL и C++ (он шёл комплектом к серверу), но оказались они по итогу именно в папке сервера). Далее пишу CMakeLists.txt:
cmake_minimum_required (VERSION 3.8)#установил минимальную версию(шаблон)
project (AdminPanel)#Да начал я с админки
add_executable(AdminPanel "main.cpp")#добавил cpp файл
target_include_directories(AdminPanel PRIVATE "include")
#дабы использовать либы из include
find_library(LIBMYSQL NAMES libmysql.lib PATHS ${PROJECT_SOURCE_DIR})
#найти либу libmysql.lib и записать её абсолютный путь в LIBMYSQL
if(LIBMYSQL)#коли либа есть, то линкуем её!
target_link_libraries(AdminPanel PRIVATE "${LIBMYSQL}")
else()#коли нет - код=death;
message(FATAL_ERROR "libmysql.lib not found\n")
endif()
find_file(DLLMYSQL NAMES "libmysql.dll" PATHS $)
#найти libmysql.dll в папке с exe файлом
if(NOT DLLMYSQL)#коли нет её там
find_file(DLLMYSQL NAMES "libmysql.dll" PATHS ${PROJECT_SOURCE_DIR})
#то ищем в корневом каталоге!
if(DLLMYSQL)#коли нашли, то копируем к exe!
add_custom_command(TARGET AdminPanel POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${DLLMYSQL}"
$)
else()#иначе смерть.
message(FATAL_ERROR "\nlibmysql.dll not found\n")
endif()
endif()
unset(DLLMYSQL CACHE)#удаляем переменную из кэша(надо, без этого работать не будет)
unset(LIBMYSQL CACHE)#удаляем переменную из кэшаX2
Да, find’ы тут явно лишние, но что сделано, то сделано, они не мешают!!!
Админка
А начну я с небольшого теста работоспособности MySQL (или внебрачного сына документации и моей лени):
#include
#include
#include
#include
#pragma comment(lib, "libmysql.lib")
MYSQL *conn;
void exiting()//Закрыли прогу преждевременно? Не беда!
{
mysql_close(conn);
}
int main()
{
// Получаем дескриптор соединения
conn = mysql_init(NULL);
if (conn == NULL)
{
// Если дескриптор не получен – выводим сообщение об ошибке
fprintf(stderr, "Error: can'tcreate MySQL-descriptor\n");
}
// Подключаемся к серверу
if (!mysql_real_connect(conn, "localhost", "Spidery", "1322213222Mz", "World", NULL, NULL, 0))
{
// Если нет возможности установить соединение с сервером
// базы данных выводим сообщение об ошибке
fprintf(stderr, "Error: can't connect to database %s\n", mysql_error(conn));
}
else
{
std::string S = "";//В ней храним введённый запрос
while (S != "cls" && S != "close")//сам знаю, что перед закрытием
//код ещё один цикл сделает, но это тест мне плевать
{
getline(std::cin, S);//Вводим строку
if (mysql_query(conn, S.c_str()))//Отправляем запрос на сервер
{
fprintf(stderr, "Error with query\nYour input: //не вышло если
std::cout << S << '\n';//Что с запросом не так.
}
else // Если запрос успешно отправлен
{
MYSQL_RES *result = mysql_store_result(conn);
if (result) // забрать весь результат
{
MYSQL_ROW row;
while (row = mysql_fetch_row(result))//выводим каждую строку отдельно
{
std::cout << *row << '\n';
}
// пока есть строки результата(Вот такая вот матрёшка)
}
else if (mysql_field_count(conn) != 0) // коли нет результата, то и бог с ним, но вот если ошибка!!!
{
mysql_free_result(result);
fprintf(stderr, "Error: %s\n", mysql_error(conn));
}
mysql_free_result(result);
}
}
}
system("cls");//работаю в терминале VSCode, потому и очищаю его
return 0;
}
*На этом пока всё, ждите, верьте, надейтесь, но лучше отпишите коммент и идите дальше*