<commit_before>#ifdef HAVE_NETWORKING

#include "util/bitmap.h"
#include "client.h"
#include "input/keyboard.h"
#include "input/input-map.h"
#include "input/input-manager.h"
#include "input/text-input.h"
#include "init.h"
#include "globals.h"
#include "util/funcs.h"
#include "util/font.h"
#include "util/file-system.h"
#include "level/utils.h"
#include "factory/font_render.h"
#include "factory/object_factory.h"
#include "factory/heart_factory.h"
#include "game/world.h"
#include "music.h"
#include "object/character.h"
#include "object/player.h"
#include "object/network_character.h"
#include "object/network_player.h"
#include "network_world_client.h"
#include "game/game.h"
#include "game/mod.h"
#include "exceptions/exception.h"
#include "loading.h"
#include "chat_client.h"
#include "network.h"
#include "configuration.h"
#include "util/system.h"
#include <string>
#include <sstream>

using namespace std;

namespace Network{

static bool uniqueId( const vector< Paintown::Object * > & objs, Paintown::Object::networkid_t id ){
    for ( vector< Paintown::Object * >::const_iterator it = objs.begin(); it != objs.end(); it++ ){
        Paintown::Object * o = *it;
        if ( o->getId() == id ){
            return false;
        }
    }
    return true;
}

/* send ok to server, get an ok back */
static void waitForServer(Socket socket){
    Message ok;
    ok << World::OK;
    ok.send( socket );
    Global::debug( 1 ) << "Sent ok " << endl;
    Message ok_ack(socket);
    int type;
    ok_ack >> type;
    if (type != World::OK){
        Global::debug(0) << "Did not receive ok from the server, instead received " << type << ". Badness may ensure" << endl;
    }
    Global::debug( 1 ) << "Received ok " << endl;
}

static void sendDummy(Socket socket){
    Message dummy;
    dummy.id = 0;
    dummy << World::IGNORE_MESSAGE;
    dummy.send( socket );
}

static void sendQuit(Socket socket){
    Message quit;
    quit.id = 0;
    quit << World::QUIT;
    quit.send(socket);
}

static Paintown::Player * createNetworkPlayer(Socket socket){
    /* TODO: get the info from the server */
    Level::LevelInfo info;
    /* remap will be modified by the selectPlayer method */
    int remap = 0;
    Filesystem::AbsolutePath playerPath = Paintown::Mod::getCurrentMod()->selectPlayer("Pick a player", info, remap);
    Paintown::Player * player = new Paintown::Player(playerPath);
    player->setMap(remap);
    ((Paintown::Player *) player)->ignoreLives();
    Filesystem::RelativePath path = Filesystem::cleanse(playerPath);

    // path.erase( 0, Util::getDataPath().length() );

    // Loader::startLoading( &loadingThread );

    /* send the path of the chosen player */
    Message create;
    create << World::CREATE_CHARACTER;
    create.path = path.path();
    create.send(socket);

    /* get the id from the server */
    Message myid(socket);
    int type;
    int alliance;
    myid >> type;
    Paintown::Object::networkid_t client_id = (Paintown::Object::networkid_t) -1;
    if (type == World::SET_ID){
        myid >> client_id >> alliance;
        player->setId(client_id);
        player->setAlliance(alliance);
        Global::debug(1) << "Client id is " << client_id << endl;
    } else {
        Global::debug(0) << "Bogus message, expected SET_ID(" << World::SET_ID << ") got " << type << endl;
    }

    return player;
}

/* TODO: simplify this code */
static void playGame(Socket socket){
    // Util::Thread::Id loadingThread;
    try{
        Paintown::Player * player = createNetworkPlayer(socket);
        vector<Paintown::Object *> players;
        players.push_back(player);

        map<Paintown::Object::networkid_t, string> clientNames;

        bool done = false;
        while (! done){
            Message next(socket);
            int type;
            next >> type;
            switch (type){
                case World::CREATE_CHARACTER : {
                    Paintown::Object::networkid_t id;
                    int alliance;
                    next >> id >> alliance;
                    if (uniqueId(players, id)){
                        Global::debug(1) << "Create a new network player id " << id << " alliance " << alliance << endl;
                        Paintown::Character * c = new Paintown::NetworkPlayer(Filesystem::find(Filesystem::RelativePath(next.path)), alliance);
                        c->setId(id);
                        ((Paintown::NetworkCharacter *)c)->alwaysShowName();
                        players.push_back(c);
                    }
                    break;
                }<commit_msg>show loader while network client is waiting for confirmation from the server<commit_after>#ifdef HAVE_NETWORKING

#include "util/bitmap.h"
#include "client.h"
#include "input/keyboard.h"
#include "input/input-map.h"
#include "input/input-manager.h"
#include "input/text-input.h"
#include "init.h"
#include "globals.h"
#include "util/funcs.h"
#include "util/font.h"
#include "util/file-system.h"
#include "level/utils.h"
#include "factory/font_render.h"
#include "factory/object_factory.h"
#include "factory/heart_factory.h"
#include "game/world.h"
#include "music.h"
#include "object/character.h"
#include "object/player.h"
#include "object/network_character.h"
#include "object/network_player.h"
#include "network_world_client.h"
#include "game/game.h"
#include "game/mod.h"
#include "exceptions/exception.h"
#include "loading.h"
#include "chat_client.h"
#include "network.h"
#include "configuration.h"
#include "util/system.h"
#include <string>
#include <sstream>

using namespace std;

namespace Network{

static bool uniqueId( const vector< Paintown::Object * > & objs, Paintown::Object::networkid_t id ){
    for ( vector< Paintown::Object * >::const_iterator it = objs.begin(); it != objs.end(); it++ ){
        Paintown::Object * o = *it;
        if ( o->getId() == id ){
            return false;
        }
    }
    return true;
}

/* send ok to server, get an ok back */
static void waitForServer(Socket socket){
    Message ok;
    ok << World::OK;
    ok.send( socket );
    Global::debug( 1 ) << "Sent ok " << endl;
    Message ok_ack(socket);
    int type;
    ok_ack >> type;
    if (type != World::OK){
        Global::debug(0) << "Did not receive ok from the server, instead received " << type << ". Badness may ensure" << endl;
    }
    Global::debug( 1 ) << "Received ok " << endl;
}

static void sendDummy(Socket socket){
    Message dummy;
    dummy.id = 0;
    dummy << World::IGNORE_MESSAGE;
    dummy.send( socket );
}

static void sendQuit(Socket socket){
    Message quit;
    quit.id = 0;
    quit << World::QUIT;
    quit.send(socket);
}

/* select a player through the usual select screen then tell the server
 * about our existence and get back an id for the player
 */
static Paintown::Player * createNetworkPlayer(Socket socket){
    class Context: public Loader::LoadingContext {
    public:
        Context(Socket socket, Level::LevelInfo & info, const Filesystem::AbsolutePath & playerPath, int remap):
        socket(socket),
        info(info),
        playerPath(playerPath),
        remap(remap),
        player(NULL){
        }

        Socket socket;
        Level::LevelInfo & info;
        const Filesystem::AbsolutePath & playerPath;
        int remap;
        Paintown::Player * player;

        virtual void load(){
            player = new Paintown::Player(playerPath);
            player->setMap(remap);
            player->ignoreLives();
            Filesystem::RelativePath cleanPath = Filesystem::cleanse(playerPath);

            /* send the path of the chosen player */
            Message create;
            create << World::CREATE_CHARACTER;
            create.path = cleanPath.path();
            create.send(socket);

            /* get the id from the server */
            Message myid(socket);
            int type;
            int alliance;
            myid >> type;
            Paintown::Object::networkid_t client_id = (Paintown::Object::networkid_t) -1;
            if (type == World::SET_ID){
                myid >> client_id >> alliance;
                player->setId(client_id);
                player->setAlliance(alliance);
                Global::debug(1) << "Client id is " << client_id << endl;
            } else {
                Global::debug(0) << "Bogus message, expected SET_ID(" << World::SET_ID << ") got " << type << endl;
            }
        }
    };

    /* TODO: get the info from the server */
    Level::LevelInfo info;

    /* remap will be modified by the selectPlayer method */
    int remap = 0;
    Filesystem::AbsolutePath playerPath = Paintown::Mod::getCurrentMod()->selectPlayer("Pick a player", info, remap);

    Context context(socket, info, playerPath, remap);
    Loader::loadScreen(context, info);
    return context.player;
}

/* TODO: simplify this code */
static void playGame(Socket socket){
    // Util::Thread::Id loadingThread;
    try{
        Paintown::Player * player = createNetworkPlayer(socket);
        vector<Paintown::Object *> players;
        players.push_back(player);

        map<Paintown::Object::networkid_t, string> clientNames;

        bool done = false;
        while (! done){
            Message next(socket);
            int type;
            next >> type;
            switch (type){
                case World::CREATE_CHARACTER : {
                    Paintown::Object::networkid_t id;
                    int alliance;
                    next >> id >> alliance;
                    if (uniqueId(players, id)){
                        Global::debug(1) << "Create a new network player id " << id << " alliance " << alliance << endl;
                        Paintown::Character * c = new Paintown::NetworkPlayer(Filesystem::find(Filesystem::RelativePath(next.path)), alliance);
                        c->setId(id);
                        ((Paintown::NetworkCharacter *)c)->alwaysShowName();
                        players.push_back(c);
                    }
                    break;
                }
{'fraction_non_alphanumeric': 0.13689465801298054, 'fraction_numerical': 0.0020968547179231155, 'mean_word_length': 2.5555555555555554, 'pattern_counts': {'":': 0, '<': 115, '<?xml version=': 0, '>': 59, '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': '4001462', 'n_tokens_mistral': 3004, 'n_tokens_neox': 2918, 'n_words': 755}