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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }