<commit_before>#include "GameServer.hpp"
#include "Deck.hpp"
#include "cards/Targetable.hpp"
#include "cards/Playable.hpp"
#include "cards/Equipped.hpp"
#include "cards/PlayerModification.hpp"
#include <cmath>

GameServer::User::User(WebSocket* ws) : ws(ws) {}
GameServer::User::User(){}

GameServer::Player::Player(){
    prepare();
    HP = maxHP;
}

int GameServer::Player::calculateDamage(int base, float mod){
    float dmg = base*mod;
    return std::ceil(dmg);
}

void GameServer::Player::prepare(){
    maxHP = 5;
    handCards = 5;
    wampir = false;
    incomingDamageMod = 1.f;
    outgoingDamageMod = 1.f;//TODO!
}

void GameServer::Player::refresh(GameServer& game){
    prepare();
    for(auto& c : equipment){
        shared_ptr<Cards::PlayerModification> mod = dynamic_pointer_cast<Cards::PlayerModification>(c);
        if(mod){
            //TODO is active??
            //cout<<"Refreshing "<<mod->getName()<<" ("<<mod->getAppliedCards().size()<<")"<<endl;
            mod->refresh(game);
            mod->apply(*this);
        }
    }
    clampHP();
    game.fillCards(*this);
}

int GameServer::Player::receiveDamage(int damage){
    int oldHP=HP;
    HP-=calculateDamage(damage,incomingDamageMod);
    clampHP();
    return oldHP-HP;
}

int GameServer::Player::giveDamage(int damage){
    return calculateDamage(damage,outgoingDamageMod);
}

void GameServer::Player::givenDamage(int damage){
    if(wampir){
        HP+=damage;
        clampHP();
    }
}

void GameServer::Player::clampHP(){
    if(HP<0) HP=0;
    if(HP>maxHP) HP=maxHP;
}

void GameServer::onConnect(WebSocket *socket)
{
	if(state == PLAYING){
		send(socket,Message("error","Game in progress. Spectating not supported").toText());
		socket->close();
		return;
	}
	connections.insert(make_pair(socket,User(socket)));
	updateUsers();
}
void GameServer::onData(WebSocket * conn, const char *data)
{
	Message m(data);
	if(handlers[m.name]){
		handlers[m.name](conn,m.data);
	}
}
void GameServer::onDisconnect(WebSocket *socket)
{
	if(state == WAITING)
		connections.erase(socket);
	else if(connections.find(socket)!=connections.end()){
		connections[socket].nickname = connections[socket].nickname + " (disconnected)";
		connections[socket].ws = nullptr;
        int pid = connections[socket].playerId;
        if(pid>=0){
            players[pid].HP = 0;
        }
		afkCount++;
		if(afkCount==connections.size()){
			cout<<"All players disconnected. Resetting game state."<<endl;
			connections.clear();
			afkCount = 0;
			resetGame();
		}
	}
	updateUsers();
}

void GameServer::broadcast(const Message& m){
	string data = m.toText();
	for (auto c : connections){
		if(c.second.ws!=nullptr)
			c.second.ws->send(data.c_str());
	}
}
void GameServer::send(WebSocket* c, const Message& m){
	if(c==nullptr) return;
	c->send(m.toText().c_str());
}

void GameServer::addCardToTable(CardPtr card){
    card->getCUID() = turnTable.size();
    turnTable.push_back(card);
    for(auto& c : card->getAppliedCards()){//add cards that were attached also (when doing a bulk playCard)
        addCardToTable(c);
    }
}

GameServer::GameServer(){
    commands["give"] = [&](WebSocket* conn, string args){
        try{
            Player& p = getPlayer(conn);
            CardPtr card = makeCardFromName(args);
            if(card!=nullptr){
                p.hand.push_back(card);
                updateCards(p);
            }
        }catch(...){

        }
    };
    commands["healall"] = [&](WebSocket* conn, string args){
        for(Player& p : players){
            p.HP = p.maxHP;
        }
    };
	handlers["login"] = [&](WebSocket* conn, json data){
		connections[conn].nickname = data["nickname"];
		updateUsers();
	};
	handlers["requestStart"] = [&](WebSocket* conn, json data){
		startPlaying();
	};
	handlers["skip"] = [&](WebSocket* conn, json data){<commit_msg>Added new commands. /sethp [playername] - sets hp /skip - finishes turn<commit_after>#include "GameServer.hpp"
#include "Deck.hpp"
#include "cards/Targetable.hpp"
#include "cards/Playable.hpp"
#include "cards/Equipped.hpp"
#include "cards/PlayerModification.hpp"
#include <cmath>

GameServer::User::User(WebSocket* ws) : ws(ws) {}
GameServer::User::User(){}

GameServer::Player::Player(){
    prepare();
    HP = maxHP;
}

int GameServer::Player::calculateDamage(int base, float mod){
    float dmg = base*mod;
    return std::ceil(dmg);
}

void GameServer::Player::prepare(){
    maxHP = 5;
    handCards = 5;
    wampir = false;
    incomingDamageMod = 1.f;
    outgoingDamageMod = 1.f;//TODO!
}

void GameServer::Player::refresh(GameServer& game){
    prepare();
    for(auto& c : equipment){
        shared_ptr<Cards::PlayerModification> mod = dynamic_pointer_cast<Cards::PlayerModification>(c);
        if(mod){
            //TODO is active??
            //cout<<"Refreshing "<<mod->getName()<<" ("<<mod->getAppliedCards().size()<<")"<<endl;
            mod->refresh(game);
            mod->apply(*this);
        }
    }
    clampHP();
    game.fillCards(*this);
}

int GameServer::Player::receiveDamage(int damage){
    int oldHP=HP;
    HP-=calculateDamage(damage,incomingDamageMod);
    clampHP();
    return oldHP-HP;
}

int GameServer::Player::giveDamage(int damage){
    return calculateDamage(damage,outgoingDamageMod);
}

void GameServer::Player::givenDamage(int damage){
    if(wampir){
        HP+=damage;
        clampHP();
    }
}

void GameServer::Player::clampHP(){
    if(HP<0) HP=0;
    if(HP>maxHP) HP=maxHP;
}

void GameServer::onConnect(WebSocket *socket)
{
	if(state == PLAYING){
		send(socket,Message("error","Game in progress. Spectating not supported").toText());
		socket->close();
		return;
	}
	connections.insert(make_pair(socket,User(socket)));
	updateUsers();
}
void GameServer::onData(WebSocket * conn, const char *data)
{
	Message m(data);
	if(handlers[m.name]){
		handlers[m.name](conn,m.data);
	}
}
void GameServer::onDisconnect(WebSocket *socket)
{
	if(state == WAITING)
		connections.erase(socket);
	else if(connections.find(socket)!=connections.end()){
		connections[socket].nickname = connections[socket].nickname + " (disconnected)";
		connections[socket].ws = nullptr;
        int pid = connections[socket].playerId;
        if(pid>=0){
            players[pid].HP = 0;
        }
		afkCount++;
		if(afkCount==connections.size()){
			cout<<"All players disconnected. Resetting game state."<<endl;
			connections.clear();
			afkCount = 0;
			resetGame();
		}
	}
	updateUsers();
}

void GameServer::broadcast(const Message& m){
	string data = m.toText();
	for (auto c : connections){
		if(c.second.ws!=nullptr)
			c.second.ws->send(data.c_str());
	}
}
void GameServer::send(WebSocket* c, const Message& m){
	if(c==nullptr) return;
	c->send(m.toText().c_str());
}

void GameServer::addCardToTable(CardPtr card){
    card->getCUID() = turnTable.size();
    turnTable.push_back(card);
    for(auto& c : card->getAppliedCards()){//add cards that were attached also (when doing a bulk playCard)
        addCardToTable(c);
    }
}

GameServer::GameServer(){
    commands["give"] = [&](WebSocket* conn, string args){
        try{
            Player& p = getPlayer(conn);
            CardPtr card = makeCardFromName(args);
            if(card!=nullptr){
                p.hand.push_back(card);
                updateCards(p);
            }
        }catch(...){

        }
    };

    commands["healall"] = [&](WebSocket* conn, string args){
        for(Player& p : players){
            p.HP = p.maxHP;
        }
    };

    commands["sethp"] = [&](WebSocket* conn, string args){
        string inputName=args.substr(0, args.find(' '));
        int newHP=stoi(args.substr(args.find(' ')));
        for(Player& p : players){
            string name = connections[p.ws].nickname;
            if(name==inputName){
                p.HP=newHP;
                p.clampHP();
                updateUsers();
                break;
            }
        }
    };

    commands["skip"] = [&](WebSocket* conn, string args){
        skipped=players.size();
    };

	handlers["login"] = [&](WebSocket* conn, json data){
		connections[conn].nickname = data["nickname"];
		updateUsers();
	};
	handlers["requestStart"] = [&](WebSocket* conn, json data){
		startPlaying();
	};
	handlers["skip"] = [&](WebSocket* conn, json data){
{'fraction_non_alphanumeric': 0.17118746232670284, 'fraction_numerical': 0.0022905364677516574, 'mean_word_length': 3.364018937401368, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5673711', 'n_tokens_mistral': 2896, 'n_tokens_neox': 2796, 'n_words': 507}