Code Search for Developers
 
 
  

connectstate.cpp from FreePop at Krugle


Show connectstate.cpp syntax highlighted

/***************************************************************************
                           connectstate.cpp
                           -------------------
    begin                : Wed Feb 2 2005
    copyright            : (C) 2005 by Brendon Lloyd Higgins
    email                : bh_doc@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <client.h>
#include <connectstate.h>
#include <loadstate.h>
#include <playerclient.h>

#include <ClanLib/core.h>
#include <ClanLib/display.h>

#include <iostream>

ConnectState::ConnectState(const CL_IPAddress& serv):
    serverIP(serv),
    netsession(0),
    nextSlot(0),
    players(0),
    me(0),
    state(AWAIT_HANDSHAKE),
    next(0) {
}

ConnectState::~ConnectState() {
}

ClientState* ConnectState::go(Client* client) {
    netsession = new CL_NetSession(Network::Session::NAME);

    CL_Surface w("gui/main/waiting", client->getResources());

    CL_Display::get_current_window()->set_cursor(
            CL_Sprite("gui/main/mice/busy", client->getResources()));

    nextSlot = new CL_Slot(
            netsession->sig_netstream_connect(Network::Channel::HANDSHAKE)
            .connect(this, &ConnectState::onNetHandshake));
    CL_Slot slotDisconnect = netsession->sig_computer_disconnected()
            .connect(this, &ConnectState::onDisconnect);
    // TODO
//     CL_Slot slotSay = netsession->sig_netpacket_receive(
//             Channel::SAY).connect(this, &ConnectState::onSay);
    CL_Slot slotAdmin = netsession->sig_netpacket_receive(
            Network::Channel::ADMIN).connect(this, &ConnectState::onAdmin);

    try {
        server = netsession->connect(serverIP);
    } catch (const CL_Error& e) {
        std::cout << "Error: " << e.message << "; Is the server running?"
                << std::endl;
        delete nextSlot;
        delete netsession;
        return 0;
    }

    while (!(next || state == FAIL)) {
        CL_Display::clear(CL_Color(127, 0, 0));
        w.draw(0, 0);
        CL_Display::flip();
        CL_System::keep_alive(50);
    }

    delete nextSlot;
    if (state == FAIL) {
        // We've failed. Die. TODO Go back to main menu.
        std::cout << "Connection failed!" << std::endl;
        for (PlayerList::iterator i = players->begin(); i != players->end();
             ++i) {
            delete *i;
        }
        delete players;
        server.disconnect("Connect failed.");
        delete netsession;
        return 0;
    } else {
        return next;
    }
}

void ConnectState::onStart(CL_NetStream& stream) {
    next = new LoadState(netsession, server, stream, players, me);
}

void ConnectState::onNetHandshake(CL_NetStream& stream) {
    stream.output.write_int32(FREEPOP_NETPROTOCOL);
    int x = stream.input.read_int32();
    if (x != FREEPOP_NETPROTOCOL) {
        std::cout << "Can't connect: Different protocol version." << std::endl;
        state = FAIL;
        return;
    }
    stream.output.write_uint8(Network::Handshake::PLAY);
    if (stream.input.read_bool8()) {
        std::cout << "Connected." << std::endl;
    } else {
        std::cout << "Connection refused." << std::endl;
        state = FAIL;
        return;
    }

    players = new PlayerList;
    int n = stream.input.read_uint32();
    if (n == 0) {
        std::cout << "No players sent from server." << std::endl;
        state = FAIL;
        return;
    }
    for (int i = 0; i < n; ++i) {
        onPlayerCreate(stream.input);
    }
    if (me == 0) {
        std::cout << "No local player sent from server." << std::endl;
        state = FAIL;
        return;
    }

    state = AWAIT_START;
    delete nextSlot;
    nextSlot = new CL_Slot(netsession->sig_netstream_connect(Network::Channel::START)
            .connect(this, &ConnectState::onStart));
    stream.output.write_bool8(true);
}

void ConnectState::onDisconnect(CL_NetComputer& computer) {
    std::cout << "Disconnected from server at "
            << computer.get_address().get_address()
            << " (" << computer.get_disconnect_reason() << ")" << std::endl;
    state = FAIL;
    if (next) {
        delete next;
        next = 0;
    }
}

void ConnectState::onAdmin(CL_NetPacket& packet, CL_NetComputer &computer) {
    // TODO Make sure it's actually from the server.
    int type = packet.input.read_int32();
    if (type == Network::Admin::PAUSE_DEMAND) {
        // Ignore
    } else if (type == Network::Admin::UNPAUSE_DEMAND) {
        // Ignore
    } else if (type == Network::Admin::PLAYER_CREATE) {
        onPlayerCreate(packet.input);
    } else if (type == Network::Admin::PLAYER_MESSAGE) {
        onPlayerMessage(packet);
    } else if (type == Network::Admin::PLAYER_REMOVE) {
        onPlayerRemove(packet);
    } else if (type == Network::Admin::STOP_DEMAND) {
        // TODO
//         logicState = END;
    }
}

void ConnectState::onPlayerCreate(CL_InputSource& is) {
    PlayerClient* pl = new PlayerClient(is);
    players->push_back(pl);
    if (pl->isLocal()) {
        me = pl;
        std::cout << "You (" << pl->getName() << " # " << pl->getSlot()
                << ") connected." << std::endl;
    } else {
        std::cout << "Player " << pl->getSlot() << " (" << pl->getName()
                << ") connected." << std::endl;
    }
}

void ConnectState::onPlayerMessage(CL_NetPacket& p) {
    int s = p.input.read_int32();
    PlayerList::iterator i;
    for (i = players->begin(); i != players->end() && (*i)->getSlot() != s;
         ++i) {
        // NO-OP.
    }
    if (i == players->end()) {
        return;
    }
    (*i)->onMessage(p);
}

void ConnectState::onPlayerRemove(CL_NetPacket& p) {
    int s = p.input.read_int32();
    int r = p.input.read_int32();
    PlayerList::iterator i;
    for (i = players->begin(); i != players->end() && (*i)->getSlot() != s;
         ++i) {
        // NO-OP.
         }
         if (i == players->end()) {
             return;
         }
         std::cout << "Player " << s << " (" << (*i)->getName()
                 << ") has gone. " << Player::Remove::STRINGS[r] << std::endl;
         players->erase(i);
}




See more files for this project here

FreePop

FreePop is a multi-platform tile-based game based on the great old game Populous 2 by Bullfrog Productions Ltd., but much improved.

Project homepage: http://sourceforge.net/projects/freepop
Programming language(s): C++
License: other

  Makefile.am
  client.cpp
  client.h
  clientmisc.cpp
  clientmisc.h
  clientstate.cpp
  clientstate.h
  connectstate.cpp
  connectstate.h
  cropsclient.cpp
  cropsclient.h
  entityclient.cpp
  entityclient.h
  entityclientfactory.cpp
  entityclientfactory.h
  firecolumnclient.cpp
  firecolumnclient.h
  gamestate.cpp
  gamestate.h
  loadstate.cpp
  loadstate.h
  mapclient.cpp
  mapclient.h
  maptileclient.cpp
  maptileclient.h
  messagebox.cpp
  messagebox.h
  oversprite.cpp
  oversprite.h
  paintable.cpp
  paintable.h
  pausefader.cpp
  pausefader.h
  peepclient.cpp
  peepclient.h
  peepmagnetclient.cpp
  peepmagnetclient.h
  playerclient.cpp
  playerclient.h
  playeroptionsdialog.cpp
  playeroptionsdialog.h
  rockclient.cpp
  rockclient.h
  swampclient.cpp
  swampclient.h
  townclient.cpp
  townclient.h
  treeclient.cpp
  treeclient.h
  worldclient.cpp
  worldclient.h