static void playerRegisterAfterLoading( P_PLAYER pc ) { if ( pc->account() == 0 ) { // We need to remove the equipment here. cBaseChar::ItemContainer container( pc->content() ); cBaseChar::ItemContainer::const_iterator it( container.begin() ); cBaseChar::ItemContainer::const_iterator end( container.end() ); for ( ; it != end; ++it ) { P_ITEM pItem = *it; if ( !pItem ) continue; pItem->remove(); } pc->del(); return; } /* else { pc->setBody(0x0190); Console::instance()->send("player: %s with bugged body-value detected, restored to male shape\n",pc->name().latin1()); }*/ }
// Main Command processing function void cCommands::process( cUOSocket *socket, const QString &command ) { if( !socket->player() ) return; P_PLAYER pChar = socket->player(); QStringList pArgs = QStringList::split( " ", command, true ); // No Command? No Processing if( pArgs.isEmpty() ) return; QString pCommand = pArgs[0].upper(); // First element should be the command // Remove it from the argument list pArgs.erase( pArgs.begin() ); // Check if the priviledges are ok if( !pChar->account()->authorized("command", pCommand.latin1() )) { socket->sysMessage( tr( "Access to command '%1' was denied" ).arg( pCommand.lower() ) ); socket->log( QString("Access to command '%1' was denied\n").arg(pCommand.lower()) ); return; } // Dispatch the command if ( dispatch( socket, pCommand, pArgs ) ) socket->log( QString( "Used command '%1'.\n" ).arg( command ) ); }
void cAccounts::reload() { QMap< SERIAL, QString > characcnames; QStringList sockaccnames; cCharIterator iterChars; P_CHAR pc; for( pc = iterChars.first(); pc; pc = iterChars.next() ) { P_PLAYER pp = dynamic_cast<P_PLAYER>(pc); if( pp && pp->account() ) { characcnames.insert( pp->serial(), pp->account()->login() ); } } cUOSocket* mSock = NULL; for( mSock = cNetwork::instance()->first(); mSock; mSock = cNetwork::instance()->next() ) { if( mSock->account() ) sockaccnames.push_back( mSock->account()->login() ); else sockaccnames.push_back( QString() ); } clear(); load(); QMap< SERIAL, QString >::Iterator it = characcnames.begin(); while( it != characcnames.end() ) { P_PLAYER pp = dynamic_cast<P_PLAYER>(FindCharBySerial( it.key() )); if( pp ) pp->setAccount( getRecord( it.data() ), false ); ++it; } QStringList::iterator sit = sockaccnames.begin(); for( mSock = cNetwork::instance()->first(); mSock; mSock = cNetwork::instance()->next() ) { if( !(*sit).isNull() ) mSock->setAccount( getRecord( (*sit) ) ); ++sit; } }
bool cSetTarget::responsed( cUOSocket* socket, cUORxTarget* target ) { P_CHAR pChar = FindCharBySerial( target->serial() ); P_ITEM pItem = FindItemBySerial( target->serial() ); cUObject* pObject = NULL; if ( pItem ) pObject = pItem; else if ( pChar ) pObject = pChar; // Only characters and items if ( !pObject ) { socket->sysMessage( tr( "Please select a valid character or item" ) ); return true; } // check for rank if ( pChar && pChar->objectType() == enPlayer ) { P_PLAYER pp = dynamic_cast<P_PLAYER>( pChar ); if ( pp->account()->rank() >= socket->player()->account()->rank() && pp != socket->player() ) { socket->sysMessage( tr( "Better do not try that!" ) ); return true; } } cVariant value( this->value ); stError* error = pObject->setProperty( key, value ); if ( error ) { socket->sysMessage( error->text ); delete error; } if ( pChar ) pChar->resend(); else if ( pItem ) pItem->update(); return true; }
/*! This handles if a character actually tries to walk (NPC & Player) */ bool cMovement::Walking( P_CHAR pChar, Q_UINT8 dir, Q_UINT8 sequence ) { if ( !pChar ) return false; // Scripting if ( pChar->onWalk( dir, sequence ) ) return false; P_PLAYER player = dynamic_cast<P_PLAYER>( pChar ); // Is the sequence in order ? if ( player && player->socket() && !verifySequence( player->socket(), sequence ) ) return false; // If checking for weight is more expensive, shouldn't we check for frozen first? if ( pChar->isFrozen() ) { if ( player && player->socket() ) player->socket()->denyMove( sequence ); return false; } // save our original location before we even think about moving const Coord oldpos( pChar->pos() ); // If the Direction we're moving to is different from our current direction // We're turning and NOT moving into a specific direction // Clear the running flag here (!) // If the direction we're moving is already equal to our current direction bool running = dir & 0x80; dir = dir & 0x7; // Remove all unneeded stuff pChar->setRunning( running ); bool turning = dir != pChar->direction(); // This happens if we're moving if ( !turning ) { // Note: Do NOT use the copy constructor as it'll create a reference Coord newCoord = calcCoordFromDir( dir, pChar->pos() ); // Check if the stamina parameters if ( player && !consumeStamina( player, running ) ) { if ( player->socket() ) player->socket()->denyMove( sequence ); return false; } // Check if we're going to collide with characters if ( player ) { // Player vs characters if ( player->socket() && player->pos().map == 0 && !player->account()->isStaff() ) { // Currently hard-limiting collisions to Felucca; this should be a server option! MapCharsIterator charCollisions = MapObjects::instance()->listCharsAtCoord( newCoord ); for ( P_CHAR them = charCollisions.first(); them; them = charCollisions.next() ) { if ( them == player ) continue; P_PLAYER otherplayer = dynamic_cast<P_PLAYER>( them ); if ( otherplayer && otherplayer->account()->isStaff() ) continue; // no collisions against the staff if ( wpAbs<SI08>( newCoord.z - them->pos().z ) < P_M_MAX_Z_CLIMB ) { // to push another char we must have maximum stamina if ( player->stamina() >= player->maxStamina() ) { player->socket()->clilocMessage( them->isHidden() ? 1019043 : 1019042 ); player->setStamina( player->stamina() - 10 ); break; } else { player->socket()->denyMove( sequence ); return false; } } } } } else { // NPC vs characters P_NPC npc = dynamic_cast<P_NPC>( pChar ); if ( npc && CheckForCharacterAtXYZ( pChar, newCoord ) ) { npc->clearPath(); return false; } } // Check if the char can move to those new coordinates // It is going to automatically calculate the new coords (!) if ( !mayWalk( pChar, newCoord ) ) { if ( player && player->socket() ) player->socket()->denyMove( sequence ); return false; } else { if ( player && player->socket() ) player->socket()->allowMove( sequence ); } // We moved so let's update our location pChar->moveTo( newCoord ); pChar->setStepsTaken( pChar->stepsTaken() + 1 ); pChar->setLastMovement( Server::instance()->time() ); checkStealth( pChar ); // Reveals the user if neccesary } else { if ( player && player->socket() ) player->socket()->allowMove( sequence ); } // do all of the following regardless of whether turning or moving i guess // set the player direction to contain only the cardinal direction bits pChar->setDirection( dir ); Coord upperLeft = pChar->pos() - Coord( ( VISRANGE + 1 ), ( VISRANGE + 1 ) ); Coord lowerRight = pChar->pos() + Coord( ( VISRANGE + 1 ), ( VISRANGE + 1 ) ); MapCharsIterator ri = MapObjects::instance()->listCharsInRect( upperLeft, lowerRight ); for ( P_CHAR observer = ri.first(); observer; observer = ri.next() ) { if ( observer == pChar ) continue; bool wasVisible = observer->pos().distance( oldpos ) < VISRANGE; // We were previously in range bool isVisible = pChar->dist( observer ) < VISRANGE; // We are now in range // If we are a player, send us new characters if ( player && player->socket() ) { // Send the observer to us if he was previously not visible and came into range recently if ( !wasVisible && isVisible ) { player->socket()->sendChar( observer ); } } // Send our movement to the observer P_PLAYER otherplayer = dynamic_cast<P_PLAYER>( observer ); if ( !otherplayer || !otherplayer->socket() ) { continue; // Skip this character, it's a player. // TODO: OnSeePlayer, OnLoosePlayer } if ( wasVisible ) { if ( isVisible ) { otherplayer->socket()->updateChar( pChar ); // We walked inside the visible range } else { otherplayer->socket()->removeObject( pChar ); // We walked out of visible range } } else if ( isVisible ) { otherplayer->socket()->sendChar( pChar ); // We walked into visible range } } // If we really moved handle teleporters and new items if ( !turning ) { handleItems( pChar, oldpos ); handleMultis( pChar, oldpos ); handleTeleporters( pChar, oldpos ); } return true; }
void cSpeech::talking( P_PLAYER pChar, const QString &lang, const QString &speech, QValueVector< UINT16 > &keywords, UINT16 color, UINT16 font, UINT8 type ) // PC speech { // handle things like renaming or describing an item if( !pChar->socket() ) return; cUOSocket *socket = pChar->socket(); if( InputSpeech( socket, pChar, speech ) ) return; // not allowed to talk if( pChar->isMuted() ) { socket->sysMessage( tr( "You re squelched and cannot talk" ) ); return; } pChar->unhide(); // Check for Bogus Color if( !isNormalColor( color ) ) color = 0x2; if( type == 0 || type == 2) pChar->setSaycolor( color ); if( SrvParams->speechLog() ) { QFile lFile( "speech.log" ); if( lFile.open( IO_Append ) ) { QString logMessage( "[%1] %2: %3 [%4, 0x%5]" ); logMessage = logMessage.arg( QDateTime::currentDateTime().toString() ).arg( pChar->name() ).arg( speech ).arg( pChar->account()->login() ).arg( pChar->serial(), 8, 16 ); lFile.writeBlock( logMessage.latin1(), logMessage.length() ); lFile.close(); } } if( pChar->onTalk( type, color, font, speech, lang ) ) return; if( ( type == 0x09 ) && ( pChar->mayBroadcast() ) ) { pChar->talk( speech, color, type ); return; } pChar->talk( speech, color, type ); QString speechUpr = speech.upper(); if( response( socket, pChar, speech, keywords ) ) return; // Vendor responded already // 0x0007 -> Speech-id for "Guards" for( QValueVector< UINT16 >::const_iterator iter = keywords.begin(); iter != keywords.end(); ++iter ) { UINT16 keyword = *iter; if( keyword == 0x07 ) pChar->callGuards(); } // well,i had a strange problem with duplicate speech input // its quite easy to understand.... // the former loop searched for the tiller man and when it // was found, the speechInput method of that boat was called. // in this method the tiller had been removed from the mapregion // and appended to the end of the cell vector... hence, the // tiller was found twice... // therefore we produce a QPtrList of cBoat* pointers and // then go through it for applying speech --- sereg RegionIterator4Items rj( pChar->pos() ); QPtrList< cBoat > pboats; for( rj.Begin(); !rj.atEnd(); rj++ ) { P_ITEM pi = rj.GetData(); if( !pi ) continue; if( pi->type() == 117 && pi->tags().get( "tiller" ).toInt() == 1 ) { cBoat* pBoat = dynamic_cast< cBoat* >(FindItemBySerial( pi->tags().get("boatserial").toInt() )); if( pBoat ) pboats.append( pBoat ); } } QPtrListIterator< cBoat > pit( pboats ); while( pit.current() ) { pit.current()->speechInput( socket, speechUpr ); ++pit; } // this makes it so npcs do not respond to isDead people - HEALERS ?? if( pChar->isDead() ) return; /* P_CHAR pc = NULL; ??? P_CHAR pNpc = NULL; RegionIterator4Chars ri( pChar->pos() ); for( ri.Begin(); !ri.atEnd(); ri++ ) { pc = ri.GetData(); if (!pc->isSameAs( pChar ) && pc->isNpc() && pc->dist( pChar ) <= 2) { pNpc = pc; break; } } */ }
void cParty::handlePacket( cUOSocket* socket, cUOPacket* packet ) { unsigned char subcommand = ( *packet )[5]; QString message; P_PLAYER leader = 0; P_PLAYER player = socket->player(); switch ( subcommand ) { // Add a member to the party case 1: socket->clilocMessage( 1005454 ); socket->attachTarget( new cPartyInvitation( player->serial() ) ); break; // Remove member from party. case 2: if ( packet->size() == 10 ) { P_PLAYER target = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) ); if ( target && player->party() && target->party() ) { if ( player->party() == target->party() && player->party()->leader() == player ) { socket->log( LOG_TRACE, tr( "Removed '%1' from the party.\n" ).arg( target->account()->login() ) ); player->party()->removeMember( target ); } else if ( target == player ) { socket->log( LOG_TRACE, tr( "Left the party.\n" ).arg( player->account()->login() ) ); player->party()->removeMember( target ); } } } break; // Send a single party member a message case 3: if ( player->party() ) { P_PLAYER target = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) ); if ( target ) { socket->log( LOG_TRACE, tr( "Told '%1' in party '%2'.\n" ).arg( target->account()->login() ).arg( message ) ); QString message = packet->getUnicodeString( 10, packet->size() - 10 ); player->party()->send( player, target, message ); } } break; // Send the whole party a message case 4: if ( player->party() ) { QString message = packet->getUnicodeString( 6, packet->size() - 6 ); socket->log( LOG_TRACE, tr( "Told the whole party: '%1'.\n" ).arg( message ) ); player->party()->send( player, message ); } break; // Allow or Disallow my party from looting my corpse case 6: if ( player->party() && packet->size() == 7 ) { bool allowed = ( *packet )[6] != 0; player->party()->setLootingAllowed( player, allowed ); socket->clilocMessage( allowed ? 1005447 : 1005448 ); } break; // Accept party invitation case 8: Timers::instance()->dispel( player, 0, "cancelpartyinvitation", true, false ); leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) ); if ( leader && leader->party() && leader->party()->canidates().contains( player ) ) { leader->party()->addMember( player ); socket->log( tr( "Accepted party invitation from '%1'.\n" ).arg( leader->account()->login() ) ); } break; // Decline party invitation case 9: Timers::instance()->dispel( player, 0, "cancelpartyinvitation", true, false ); leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( packet->getInt( 6 ) ) ); if ( leader && leader->party() && leader->party()->canidates().contains( player ) ) { leader->socket()->clilocMessageAffix( 1008091, 0, player->name(), 0x3b2, 3, 0, false, true ); leader->party()->removeMember( player ); socket->clilocMessage( 1008092 ); socket->log( LOG_TRACE, tr( "Declined party invitation from '%1'.\n" ).arg( leader->account()->login() ) ); } break; default: message.sprintf( "Receieved unknown party subcommand: 0x%02x", subcommand ); message += packet->dump( packet->uncompressed() ) + "\n"; socket->log( LOG_WARNING, message ); break; }; }
bool responsed( cUOSocket* socket, cUORxTarget* target ) { if ( !isCharSerial( target->serial() ) ) { socket->clilocMessage( 1005442 ); } else { P_PLAYER leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( this->player ) ); P_CHAR character = World::instance()->findChar( target->serial() ); P_NPC npc = dynamic_cast<P_NPC>( character ); P_PLAYER player = dynamic_cast<P_PLAYER>( character ); if ( !leader || ( leader->party() && leader->party()->leader() != leader ) ) { socket->clilocMessage( 1005453 ); } else if ( leader->party() && leader->party()->members().count() + leader->party()->canidates().count() >= 10 ) { socket->clilocMessage( 1008095 ); // NPC targetted } else if ( npc ) { if ( npc->isHuman() ) socket->clilocMessage( 1005443, 0, npc->saycolor(), 3, npc ); else socket->clilocMessage( 1005444 ); } else if ( leader == player ) { socket->clilocMessage( 1005439 ); } else if ( player && player->party() && player->party() == leader->party() ) { socket->clilocMessage( 1005440 ); } else if ( player && leader->party() && leader->party()->canidates().contains( player ) ) { socket->clilocMessage( 1005440 ); } else if ( player && player->party() ) { socket->clilocMessage( 1005441 ); } else if ( player && player->socket() ) { if ( !leader->party() ) { new cParty( leader ); leader->party()->update(); } player->socket()->clilocMessageAffix( 1008089, 0, leader->name(), 0x3b2, 3, 0, false, true ); leader->party()->addCanidate( player ); socket->log( LOG_TRACE, tr( "Invited '%1' to join his party.\n" ).arg( player->account()->login() ) ); // Send a party invitation request cUOTxPartyInvitation invitation; invitation.setSerial( leader->serial() ); player->socket()->send( &invitation ); // Attach a tempeffect that'll cancel the invitation after ten seconds Timers::instance()->insert( new cPartyCancelInvitation( leader->serial(), player->serial() ) ); } } return true; }
/*! Remove the canidate from the party and notify him. */ void Expire() { // Check if the player is still waiting for the party acceptance P_PLAYER leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( this->leader ) ); P_PLAYER player = dynamic_cast<P_PLAYER>( World::instance()->findChar( destSer ) ); // Only send a decline party invitation packet if the player really is // still invited to join the party if ( leader && leader->party() && player && player->socket() && leader->party()->canidates().contains( player ) ) { player->socket()->log( LOG_TRACE, tr( "Party invitation from '%1' timed out.\n" ).arg( leader->account()->login() ) ); leader->party()->removeMember( player ); // This automatically resends and checks the party } }