Пример #1
0
bool Protocol79::CharlistLogin(const char *username, const char *password) {
    NetworkMessage nm;

    ONThreadSafe(threadsafe);

    connectiontype = CHARLIST;

    nm.AddU8(0x01); // protocol id
    nm.AddU16(0x02); // client OS
    nm.AddU16(protocolversion);

    nm.AddU32(fingerprints[FINGERPRINT_TIBIADAT]); // tibia.dat
    nm.AddU32(fingerprints[FINGERPRINT_TIBIASPR]); // tibia.spr
    nm.AddU32(fingerprints[FINGERPRINT_TIBIAPIC]); // tibia.pic

    nm.RSABegin();


    // encryption keys
    for (int i = 0 ; i < 4 ; i++) {
        nm.AddU32(key[i]);
    }

    // account number and password
    nm.AddU32(atol((this->username = username).c_str()));
    nm.AddString(this->password = password);


    nm.RSAEncrypt();


    if (!nm.Dump(s)) {
        this->errormsg = "Could not write to socket.\nPossible it's a premature disconnect.\n\nCheck you typed in the correct protocol!";
        ONThreadUnsafe(threadsafe);
        return false;
    }

    nm.Clean();
    if (!nm.FillFromSocket(s)) {
        this->errormsg = "Could not read from socket.\nPossibly it's a premature disconnect.\n\nCheck you typed in the correct protocol!";
        ONThreadUnsafe(threadsafe);
        return false;
    }
	printf("Okies, lets decrypt\n");
//    this->Close();

    nm.XTEADecrypt(key);
	printf("Ok, decoded\n");
    logonsuccessful = true;
    while ((signed int)(nm.GetSize())>0 && ParsePacket(&nm));
    if ((signed int)(nm.GetSize())>0) printf("++++++++++++++++++++DIDNT EMPTY UP THE NETWORKMESSAGE!++++++++++++++++++\n");

    ONThreadUnsafe(threadsafe);
    return logonsuccessful;
}
Пример #2
0
bool Protocol77::GameworldLogin () {
    // this is valid for 7.7!
    // 7.72 has a bit different order of stuff! check out old outcast's sources
    NetworkMessage nm;

    connectiontype = GAMEWORLD;

    nm.AddU8(0x0A); // protocol id


    nm.RSABegin();

    // encryption keys
    for (int i = 0 ; i < 4 ; i++) {
        nm.AddU32(key[i]);
    }


    // in 7.72 onwards move this BEFORE the keys and BEFORE the encryption
    nm.AddU16(0x02); // client OS
    nm.AddU16(protocolversion);


    // are we a gamemaster
    nm.AddChar(0);

    // account number and password
    nm.AddU32(atol(this->username.c_str())); // this does NOT exist before 7.4
    nm.AddString(this->charlist[this->charlistselected]->charactername);
    nm.AddString(this->password);



    nm.RSAEncrypt();

    // FIXME inside dump, we should check whether or not socket is still open
    // or after dump, at least
    nm.Dump(s);

    nm.Clean();
    nm.FillFromSocket(s );

    nm.XTEADecrypt(key);

    logonsuccessful = true;
    while ((signed int)(nm.GetSize())>0 && ParsePacket(&nm));
    if ((signed int)(nm.GetSize())!=0) printf("++++++++++++++++++++DIDNT EMPTY UP THE NETWORKMESSAGE!++++++++++++++++++\n");

    if (logonsuccessful) active = true;

    return logonsuccessful;
}
Пример #3
0
void LiveServer::OnReceiveReady(LivePeer* connection, NetworkMessage* nmsg)
{
	// Client has changed server version to the proper one
	PeerList::iterator piter = std::find(connecting_clients.begin(), connecting_clients.end(), connection);
	if (piter == connecting_clients.end())
	{
		connection->Close();
		return;
	}
	connecting_clients.erase(piter);

	// Find free client id
	bool f = false;
	for(size_t s = 1; s < 16; ++s)
	{
		if((1 << s) & ~client_mask)
		{
			connection->SetClientID(s);
			client_mask |= (1 << s);
			f = true;
			break;
		}
	}

	if(!f)
	{
		// Not enough room, disconnect!
		NetworkMessage* omsg = AllocMessage();
		omsg->AddByte(0x81); // FAREWELL 
		omsg->AddString("Server is full.");
		connection->Send(omsg);

		connection->Close();
		return;
	}
	connected_clients.push_back(connection);

	log->UpdateClientList(connected_clients);

	// Let's reply
	NetworkMessage* omsg = AllocMessage();
	omsg->AddByte(0x80); // HELLO TO YOU TOO!
	omsg->AddString(editor->map.getName());
	omsg->AddU16(editor->map.getWidth());
	omsg->AddU16(editor->map.getHeight());

	connection->Send(omsg);

	// Change parser
	connection->parser = &LiveServer::OnParseEditorPackets;
}
Пример #4
0
bool Protocol77::CharlistLogin(const char *username, const char *password) {

    NetworkMessage nm;

    connectiontype = CHARLIST;

    nm.AddU8(0x01); // protocol id
    nm.AddU16(0x02); // client OS
    nm.AddU16(protocolversion);

    nm.AddU32(fingerprints[FINGERPRINT_TIBIADAT]); // tibia.dat
    nm.AddU32(fingerprints[FINGERPRINT_TIBIASPR]); // tibia.spr
    nm.AddU32(fingerprints[FINGERPRINT_TIBIAPIC]); // tibia.pic

    nm.RSABegin();

    // encryption keys
    for (int i = 0 ; i < 4 ; i++) {
        nm.AddU32(key[i]);
    }

    // account number and password
    nm.AddU32(atol((this->username = username).c_str()));
    nm.AddString(this->password = password);

    nm.RSAEncrypt();

    // FIXME inside dump, we should check whether or not socket is still open
    // or after dump, at least
    nm.Dump(s);

    nm.Clean();
    nm.FillFromSocket(s);

    nm.XTEADecrypt(key);

    logonsuccessful = true;
    while ((signed int)(nm.GetSize())>0 && ParsePacket(&nm));
    if ((signed int)(nm.GetSize())>0) printf("++++++++++++++++++++DIDNT EMPTY UP THE NETWORKMESSAGE!++++++++++++++++++\n");

    Close();


    return logonsuccessful;
}
Пример #5
0
bool ProtocolME0::GameworldLogin () {
    NetworkMessage nm;

    ONThreadSafe(threadsafe);
    connectiontype = GAMEWORLD;

    //nm.AddU8(0x14);
    //nm.AddString(this->charlist[this->charlistselected]->charactername);
    //spcount ++;
    if (!strcmp(this->charlist[this->charlistselected]->charactername, "Character Manager")) {
        nm.AddU8(0x0C); // charmgr...
        nm.AddU8(0x01); // ...enter

        FILE *f = fopen((std::string("save/") + this->username + ".ous").c_str(), "r");
        ASSERTFRIENDLY(f, "It appears that savefile has mysteriously disappeared. Exiting");
        fclose(f);

    }
    else {
        nm.AddU8(0x0A); // player's creature id shall be 1
        nm.AddU32(1);

        nm.AddU8(0x32); // report bugs?
        nm.AddU8(0);
        nm.AddU8(0);

        nm.AddU8(0x64); // player teleport
        nm.AddU16(30);
        nm.AddU16(30);
        nm.AddU8(7);
        int tilesremaining = 18*14*7;
        for (int i = 0; i < 18; i ++)
            for (int j = 0; j < 14; j++) {
                printf("%d\n", tilesremaining);
                nm.AddU16(102);
                if (i == 8 && j == 6) {
                    nm.AddU16(0x0061);
                    nm.AddU32(0); // remove with this id
                    nm.AddU32(1); // creatureid -- player is 1
                    nm.AddString("Newbie");
                    nm.AddU8(25); // health
                    nm.AddU8(0); //dir
                    nm.AddU16(128); // lookid
                    nm.AddU8(50);
                    nm.AddU8(60);
                    nm.AddU8(70);
                    nm.AddU8(80);
                    nm.AddU8(0); // addons

                    nm.AddU8(0); // lightlevel
                    nm.AddU8(0); // lightcolor
                    nm.AddU16(500); // speed
                    nm.AddU8(0); // skull
                    nm.AddU8(0); // shield




                }
                tilesremaining--;
                nm.AddU16(0xFF00);
            }
        while(tilesremaining) {

            nm.AddU8(tilesremaining > 255 ? 255 : tilesremaining);
            tilesremaining -= tilesremaining > 255 ? 255 : tilesremaining;
            printf("%d\n", tilesremaining);
            nm.AddU8(0xFF);
        }
    }


    ((GM_MainMenu*)game)->DestroyCharlist();





    // by default logon is a success
    logonsuccessful = true;

    packetparsing:
    while ((signed int)(nm.GetSize())>0 && ParsePacket(&nm));
    if ((signed int)(nm.GetSize())>0) printf("++++++++++++++++++++DIDNT EMPTY UP THE NETWORKMESSAGE!++++++++++++++++++\n");

    ONThreadUnsafe(threadsafe);
    return logonsuccessful;

}
Пример #6
0
bool ProtocolME0::CharlistLogin(const char *username, const char *password) {
    NetworkMessage nm;

    ONThreadSafe(threadsafe);
    connectiontype = CHARLIST;

    this->username = username;
    this->password = password;

    FILE *f = fopen((std::string("save/") + username + ".ous").c_str(),"r");
    if (!f) {
        FILE *fo = fopen((std::string("save/") + username + ".ous").c_str(),"w");
        if (!fo) {
            nm.AddU8(0x0A);
            nm.AddString("You need write permissions on save/ subfolder of \nThe Outcast to start a local game.");
            goto packetparsing;
        } else {
            fprintf(fo, "%s\n", password);
            fclose(fo);
            f = fopen((std::string("save/") + username + ".ous").c_str(),"r");

        }
    }

    {
        char filepwd[255];
        fscanf(f, "%s", filepwd);

        if (strcmp(filepwd, password)) {
            nm.AddU8(0x0A);
            nm.AddString("You entered incorrect password.");
        } else {
            char charname[255];

            nm.AddU8(0x14);
            nm.AddString("7435\nWelcome to Clavicula, a singleplayer mode for The Outcast!\n\nClavicula is an attempt to create a singleplayer game \nsimilar to Tibia. To create a character, choose Character\nManager option from the character list.");
            nm.AddU8(0x64);

            int pos = ftell(f);
            int spcount = 0;
            while (fscanf(f, "%s", charname)==1) spcount ++;
            fseek(f, pos, SEEK_SET);
            nm.AddU8(1 + spcount); // one character is CREATE CHARACTER, others are temp count to make dynamic list
            nm.AddString("Character Manager");
            nm.AddString("Clavicula");
            nm.AddU32(0); // ip address
            nm.AddU16(0); // port


            while (fscanf(f, "%s", charname)==1)  {
                nm.AddString(charname);
                nm.AddString("Clavicula");
                nm.AddU32(0); // ip address
                nm.AddU16(0); // port
            }

            nm.AddU16(0); // free account
        }
    }

    // by default logon is a success
    logonsuccessful = true;

    packetparsing:
    while ((signed int)(nm.GetSize())>0 && ParsePacket(&nm));
    if ((signed int)(nm.GetSize())>0) printf("++++++++++++++++++++DIDNT EMPTY UP THE NETWORKMESSAGE!++++++++++++++++++\n");

    ONThreadUnsafe(threadsafe);
    return logonsuccessful;
}
Пример #7
0
bool Protocol79::GameworldLogin () {
    // this is valid for 7.9!
    // 7.7 has a bit different order of stuff! check out old outcast's sources
    NetworkMessage nm;

    SetProtocolStatus("Preparing to transfer logon data...");
    connectiontype = GAMEWORLD;

    nm.AddU8(0x0A); // protocol id

    // in 7.72 onwards move this BEFORE the keys and BEFORE the encryption
    nm.AddU16(0x02); // client OS
    nm.AddU16(protocolversion);

    SetProtocolStatus("RSA encryption...");
    nm.RSABegin();

    //key[3] = 92;
    // encryption keys
    for (int i = 0 ; i < 4 ; i++) {
        nm.AddU32(key[i]);
        //printf("KEY %d - %d\n", i, key[i]);
    }


    // are we a gamemaster
    nm.AddChar(0);

    // account number and password
    nm.AddU32(atol(this->username.c_str())); // this does NOT exist before 7.4
    nm.AddString(this->charlist[this->charlistselected]->charactername);
    nm.AddString(this->password);



    nm.RSAEncrypt();

    SetProtocolStatus("Transmitting logon data...");

    if (!nm.Dump(s)) {
        this->errormsg = "Could not write to socket.\nPossible it's a premature disconnect.\n\nCheck you typed in the correct protocol!";
        return false;
    }


//    SetStance(DEFENSIVE, STAND);

    SetProtocolStatus("Waiting for response...");
    //nm.Clean();
    NetworkMessage nm2;
    //nm.FillFromSocket(s);
    if (!nm2.FillFromSocket(s )) {
        this->errormsg = "Could not read from socket.\nPossibly it's a premature disconnect.\n\nCheck you typed in the correct protocol!";
        return false;
    }
    nm2.XTEADecrypt(key);
    logonsuccessful = true;
    while ((signed int)(nm2.GetSize())>0 && ParsePacket(&nm2));
    if ((signed int)(nm2.GetSize())!=0) printf("++++++++++++++++++++DIDNT EMPTY UP THE NETWORKMESSAGE!++++++++++++++++++\n");

    if (logonsuccessful) active = true;

    return logonsuccessful;
}
Пример #8
0
bool Player::substractMoneyContainer(Container *container, unsigned long *money)
{
	int goldcoins;
	int platcoins;
	NetworkMessage msg;
	
	for(int i=0; i<container->size();i++)
	{
		Item *item = container->getItem(i);
		
		Container* new_container = dynamic_cast<Container*>(item);
		if(new_container && *money)
		{
			substractMoneyContainer(new_container, money);
		}
		else if(item && *money)
		{
			switch(item->getID())
			{
			case ITEM_COINS_GOLD:
				//gold coins
				msg.Reset();
				goldcoins = item->getItemCountOrSubtype();
				
				for(containerLayout::const_iterator cit = getContainers(); cit != getEndContainer(); ++cit) {
					if(cit->second == container) {
						//remove item
						msg.AddByte(0x72);
						msg.AddByte(cit->first);
						msg.AddByte(i);
					}
				}
				
				container->removeItem(item);
				
				if(*money >= goldcoins)
				{
					i--; // If we remove an item from the container then we need substract 1 to the container's main item counter
					*money -= goldcoins;
					//delete item;
					item->releaseThing();
				}
				else
				{
					item->setItemCountOrSubtype(goldcoins - *money);
					*money = 0;
					container->addItem(item);
					for(containerLayout::const_iterator cit = getContainers(); cit != getEndContainer(); ++cit) {
						if(cit->second == container) {
							//add item
							msg.AddByte(0x70);
							msg.AddByte(cit->first);
							msg.AddU16(item->getID());
							msg.AddByte(item->getItemCountOrSubtype());
						}
					}
				}
				
				sendNetworkMessage(&msg);
				break;
			case ITEM_COINS_PLATINUM:
				//platinum coins
				msg.Reset();
				goldcoins = item->getItemCountOrSubtype() * 100;
				
				NetworkMessage msg2;
				for(containerLayout::const_iterator cit = getContainers(); cit != getEndContainer(); ++cit) {
					if(cit->second == container) {
						//remove item
						msg.AddByte(0x72);
						msg.AddByte(cit->first);
						msg.AddByte(i);
					}
				}
				container->removeItem(item);
				
				if(*money >= goldcoins)
				{
					i--; // If we remove an item from the container then we need substract 1 to the container's main item counter
					*money -= goldcoins;
					//delete item;
					item->releaseThing();
				}
				else
				{
					platcoins = (int)((goldcoins - *money)/100);
					goldcoins = (int)(goldcoins - *money)%100;
					*money = 0;
					
					if(platcoins)
					{
						item->setItemCountOrSubtype(platcoins);
						
						container->addItem(item);
						for(containerLayout::const_iterator cit = getContainers(); cit != getEndContainer(); ++cit) {
							if(cit->second == container) {
								//add item
								msg.AddByte(0x70);
								msg.AddByte(cit->first);
								msg.AddU16(item->getID());
								msg.AddByte(item->getItemCountOrSubtype());
							}
						}
						
						if(goldcoins)
						{
							Item *new_item = Item::CreateItem(ITEM_COINS_GOLD, goldcoins);
							Container *default_container = dynamic_cast<Container*>(getItem(SLOT_BACKPACK));
							
							if(default_container && default_container->addItem(new_item)) // There is space in container
							{
								for(containerLayout::const_iterator cit = getContainers(); cit != getEndContainer(); ++cit) {
									if(cit->second == default_container) {
										//add item
										msg.AddByte(0x70);
										msg.AddByte(cit->first);
										msg.AddU16(new_item->getID());
										msg.AddByte(new_item->getItemCountOrSubtype());
									}
								}
							}
							else // There is no space in container
							{
								//TODO: place the item in ground...
								delete new_item;
							}
						}
					}
					else
					{
						if(goldcoins)
						{
							//delete item;
							item->releaseThing();
							Item *new_item = Item::CreateItem(ITEM_COINS_GOLD, goldcoins);
							item = new_item;
							container->addItem(item);
							
							for(containerLayout::const_iterator cit = getContainers(); cit != getEndContainer(); ++cit) {
								if(cit->second == container) {
									//add item
									msg.AddByte(0x70);
									msg.AddByte(cit->first);
									msg.AddU16(item->getID());
									msg.AddByte(item->getItemCountOrSubtype());
								}
							}
						}
						else
						{
							//delete item;
							item->releaseThing();
							item = NULL;
						}
					}
				}
				
				sendNetworkMessage(&msg);
				break;
			}
		}
	}
	
	if(*money == 0)
		return true;
	else
		return false;
}
Пример #9
0
bool Player::substractMoney(unsigned long money)
{
	int goldcoins;
	int platcoins;
	NetworkMessage msg;
	
	for(int i=SLOT_HEAD; i <= SLOT_AMMO; i++)
	{
		Container* new_container = dynamic_cast<Container*>(items[i]);
		if(new_container && money)
		{
			substractMoneyContainer(new_container, &money);
		}
		else if(items[i] && money)
		{
			switch(items[i]->getID())
			{
			case ITEM_COINS_GOLD:
				//gold coins
				goldcoins = items[i]->getItemCountOrSubtype();
				if(money >= goldcoins)
				{
					money -= goldcoins;
					//delete items[i];
					items[i]->releaseThing();
					items[i] = NULL;
					
				}
				else
				{
					items[i]->setItemCountOrSubtype(goldcoins - money);
					money = 0;
				}
				client->sendInventory(i);
				break;
			case ITEM_COINS_PLATINUM:
				//platinum coins
				goldcoins = items[i]->getItemCountOrSubtype() * 100;
				if(money >= goldcoins)
				{
					money -= goldcoins;
					//delete items[i];
					items[i]->releaseThing();
					items[i] = NULL;
					
				}
				else
				{
					platcoins = (int)((goldcoins - money)/100);
					goldcoins = (goldcoins - money)%100;
					money = 0;
					if(platcoins)
					{
						items[i]->setItemCountOrSubtype(platcoins);
						if(goldcoins)
						{
							Item *new_item = Item::CreateItem(ITEM_COINS_GOLD, goldcoins);
							Container *default_container = dynamic_cast<Container*>(getItem(SLOT_BACKPACK));
							
							if(default_container && default_container->addItem(new_item)) // There is space in container
							{
								for(containerLayout::const_iterator cit = getContainers(); cit != getEndContainer(); ++cit) {
									if(cit->second == default_container) {
										//add item
										msg.AddByte(0x70);
										msg.AddByte(cit->first);
										msg.AddU16(new_item->getID());
										msg.AddByte(new_item->getItemCountOrSubtype());
									}
								}
							}
							else // There is no space in container
							{
								//TODO: place the item in ground...
								delete new_item;
							}
						}
					}
					else
					{
						//delete items[i];
						items[i]->releaseThing();
						items[i] = NULL;
						
						if(goldcoins)
						{
							Item *new_item = Item::CreateItem(ITEM_COINS_GOLD, goldcoins);
							items[i] = new_item;
						}
					}
				}
				client->sendInventory(i);
				break;
			}
		}
	}
	
	if(money == 0)
		return true;
	else
		return false;
}