init
This commit is contained in:
247
src/Multiplayer.cpp
Normal file
247
src/Multiplayer.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
#include "Multiplayer.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include "Game.hpp"
|
||||
|
||||
// #define SERVER_ADDRESS "127.0.0.1"
|
||||
#define SERVER_ADDRESS "sffnetwork.su"
|
||||
|
||||
void Multiplayer::connect(const char* name) {
|
||||
printf("name %s\n", name);
|
||||
m_name = name;
|
||||
|
||||
m_state = MultiplayerState::CONNECTING;
|
||||
|
||||
client = enet_host_create(nullptr, 1, LAST_CHANNEL, 0, 0);
|
||||
if (!client) {
|
||||
printf("client null\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ENetAddress address;
|
||||
enet_address_set_host(&address, SERVER_ADDRESS);
|
||||
address.port = 7777;
|
||||
|
||||
peer = enet_host_connect(client, &address, LAST_CHANNEL, 0);
|
||||
if (peer == nullptr) {
|
||||
printf("peer null\n");
|
||||
enet_host_destroy(client);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ENetEvent event;
|
||||
auto res = enet_host_service(client, &event, 5000);
|
||||
|
||||
if (res <= 0 || event.type != ENET_EVENT_TYPE_CONNECT) {
|
||||
enet_peer_reset(peer);
|
||||
printf("Failed to connect to server!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
auto packet_size = 1 + 2 + strlen(name);
|
||||
auto login_packet = new char[packet_size];
|
||||
login_packet[0] = Header::IDENTIFICATION;
|
||||
*(uint16_t*)(login_packet + 1) = strlen(name);
|
||||
memcpy(login_packet + 3, name, strlen(name));
|
||||
|
||||
if (sendPacket(login_packet, packet_size)) {
|
||||
printf("trying to reg!!\n");
|
||||
m_state = MultiplayerState::LOGGING_IN;
|
||||
}
|
||||
}
|
||||
|
||||
int Multiplayer::sendPacket(char* data, int size, Channel channel, bool reliable) {
|
||||
auto enetPacket = enet_packet_create(data, size, reliable ? ENET_PACKET_FLAG_RELIABLE : ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
|
||||
|
||||
return enet_peer_send(peer, channel, enetPacket) == 0;
|
||||
}
|
||||
|
||||
void Multiplayer::update(float dt) {
|
||||
ENetEvent event;
|
||||
while (enet_host_service(client, &event, 0) > 0) {
|
||||
switch (event.type) {
|
||||
case ENET_EVENT_TYPE_RECEIVE: {
|
||||
// printf("packet received\n");
|
||||
|
||||
auto bytes = event.packet->data;
|
||||
|
||||
// for (int i = 0; i < event.packet->dataLength; i++) {
|
||||
// printf("%02X ", bytes[i]);
|
||||
// }
|
||||
// printf("\n");
|
||||
|
||||
switch (bytes[0]) {
|
||||
case LOAD_PLAYER: { // all players get this when a new player connects
|
||||
bytes++;
|
||||
|
||||
uint16_t nameLen = *(uint16_t*)bytes;
|
||||
bytes += 2;
|
||||
|
||||
auto name = new char[nameLen + 1];
|
||||
memcpy(name, bytes, nameLen);
|
||||
bytes += nameLen;
|
||||
name[nameLen] = 0;
|
||||
|
||||
uint32_t playerID = *(uint32_t*)bytes;
|
||||
bytes += 4;
|
||||
float serverTime = *(float*)bytes;
|
||||
|
||||
printf("- load player name %s id %i server time %f\n", name, playerID, serverTime);
|
||||
|
||||
Game::get().chatMessages.push_back({"Player " + std::string(name) + " has joined.", (float)GetTime()});
|
||||
|
||||
if (m_name == name) {
|
||||
printf("- its me!\n");
|
||||
m_id = playerID;
|
||||
m_state = MultiplayerState::PLAYING;
|
||||
Game::get().serverTime = serverTime;
|
||||
|
||||
char packet = Header::LOAD_PLAYERS;
|
||||
|
||||
sendPacket(&packet, 1);
|
||||
} else {
|
||||
// std::string texture = "assets/";
|
||||
// std::string nicknamee = name;
|
||||
// std::transform(nicknamee.begin(), nicknamee.end(), nicknamee.begin(), ::tolower);
|
||||
// texture.append(nicknamee).append(".png");
|
||||
|
||||
auto p = Player(skinFromName(name), name);
|
||||
p.pos.y = -400;
|
||||
Game::get().otherPlayers[playerID] = p;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD_PLAYERS: { // get list of all players on server with their id,pos,name
|
||||
printf("- load players packet size %i\n", event.packet->dataLength);
|
||||
|
||||
bytes++;
|
||||
|
||||
auto num = *bytes;
|
||||
bytes++;
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
auto id = *(uint32_t*)bytes;
|
||||
bytes += 4;
|
||||
auto x = *(float*)bytes;
|
||||
bytes += 4;
|
||||
auto y = *(float*)bytes;
|
||||
bytes += 4;
|
||||
|
||||
auto nameLen = *(uint16_t*)bytes;
|
||||
bytes += 2;
|
||||
|
||||
auto name = new char[nameLen + 1];
|
||||
name[nameLen] = 0;
|
||||
memcpy(name, bytes, nameLen);
|
||||
bytes += nameLen;
|
||||
|
||||
printf("- - player: x %f y %f name %s id %i\n", x, y, name, id);
|
||||
// std::string texture = "assets/";
|
||||
// std::string nicknamee = name;
|
||||
// std::transform(nicknamee.begin(), nicknamee.end(), nicknamee.begin(), ::tolower);
|
||||
// texture.append(nicknamee).append(".png");
|
||||
|
||||
auto p = Player(skinFromName(name), name);
|
||||
// auto p = Player(texture.c_str(), name);
|
||||
p.pos = {x, y};
|
||||
Game::get().otherPlayers[id] = p;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PLAYER: { // pos of all players
|
||||
bytes++;
|
||||
|
||||
auto num = *bytes;
|
||||
bytes++;
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
auto id = *(uint32_t*)bytes;
|
||||
bytes += 4;
|
||||
auto x = *(float*)bytes;
|
||||
bytes += 4;
|
||||
auto y = *(float*)bytes;
|
||||
bytes += 4;
|
||||
|
||||
if (id == peer->connectID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Game::get().otherPlayers.contains(id)) {
|
||||
auto& p = Game::get().otherPlayers[id];
|
||||
// Game::get().otherPlayers[id].pos = {x, y};
|
||||
auto delta_x = x - p.pos.x;
|
||||
p.pos = {x, y};
|
||||
p.vel.x = delta_x;
|
||||
// p.walkRight = delta_x > 0;
|
||||
if (delta_x > 0) {
|
||||
p.walkRight = true;
|
||||
} else if (delta_x < 0) {
|
||||
p.walkRight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MESSAGE: {
|
||||
bytes++;
|
||||
|
||||
auto len = *(uint16_t*)bytes;
|
||||
bytes += 2;
|
||||
|
||||
auto msg = new char[len + 1];
|
||||
msg[len] = 0;
|
||||
|
||||
memcpy(msg, bytes, len);
|
||||
|
||||
Game::get().chatMessages.push_back({msg, (float)GetTime()});
|
||||
|
||||
delete[] msg;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
printf("- unk packet %i\n", bytes[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT: {
|
||||
printf("Connection closed.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
m_updateTime += dt;
|
||||
|
||||
const auto POS_TIME = 1 / 30.f;
|
||||
if (m_updateTime > POS_TIME) {
|
||||
// printf("sending pos\n");
|
||||
m_updateTime -= POS_TIME;
|
||||
|
||||
auto data = new char[1 + 4 + 4];
|
||||
|
||||
data[0] = Header::PLAYER;
|
||||
*(float*)(data + 1) = Game::get().player.pos.x;
|
||||
*(float*)(data + 1 + 4) = Game::get().player.pos.y;
|
||||
|
||||
sendPacket(data, 1 + 4 + 4);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user