polserver/pol-core/pol/getmsg.cpp

128 lines
3.2 KiB
C++
Raw Permalink Normal View History

/** @file
*
* @par History
*/
2016-02-11 22:54:43 +01:00
#include <ctype.h>
#include <stddef.h>
2016-02-11 22:54:43 +01:00
#include "../bscript/berror.h"
#include "../bscript/impstr.h"
#include "../clib/clib_endian.h"
#include "../clib/logfacility.h"
2016-02-11 22:54:43 +01:00
#include "../clib/rawtypes.h"
#include "item/item.h"
#include "mobile/charactr.h"
#include "module/unimod.h"
2016-02-11 22:54:43 +01:00
#include "module/uomod.h"
#include "network/cgdata.h"
#include "network/client.h"
2018-01-01 21:49:30 +01:00
#include "network/packethelper.h"
#include "network/packets.h"
2018-12-30 21:35:54 +01:00
#include "network/pktboth.h"
2016-02-11 22:54:43 +01:00
#include "ufunc.h"
#include "uoexec.h"
namespace Pol
{
namespace Core
{
void send_prompt( Network::Client* client, u32 serial )
{
Network::PktHelper::PacketOut<Network::PktOut_9A> msg;
msg->WriteFlipped<u16>( sizeof msg->buffer );
msg->Write<u32>( serial );
msg->WriteFlipped<u32>( 0x15u );
msg->offset += 5; // u32 type u8 text[0]
msg.Send( client );
}
2016-02-11 22:54:43 +01:00
void handle_prompt( Network::Client* client, PKTBI_9A* msg )
{
Module::UOExecutorModule* uoemod = client->gd->prompt_uoemod;
2018-07-31 14:30:29 +02:00
if ( uoemod == nullptr )
return;
auto& uoex = uoemod->uoexec();
int textlen = cfBEu16( msg->msglen ) - offsetof( PKTBI_9A, text );
if ( msg->type && textlen > 0 )
{
if ( textlen <= 120 && msg->text[textlen - 1] == '\0' )
2016-02-11 22:54:43 +01:00
{
bool ok = true;
--textlen; // don't include null terminator (already checked)
for ( int i = 0; i < textlen; ++i )
2016-02-11 22:54:43 +01:00
{
if ( !isprint( msg->text[i] ) )
2016-02-11 22:54:43 +01:00
{
ok = false;
break;
2016-02-11 22:54:43 +01:00
}
}
if ( ok )
{
Bscript::String* str = new Bscript::String( msg->text, static_cast<size_t>( textlen ),
Bscript::String::Tainted::YES );
uoex.ValueStack.back().set( new Bscript::BObject( str ) );
}
2016-02-11 22:54:43 +01:00
}
}
uoex.revive();
2018-07-31 14:30:29 +02:00
uoemod->prompt_chr = nullptr;
client->gd->prompt_uoemod = nullptr;
}
2018-12-30 21:35:54 +01:00
} // namespace Core
namespace Module
{
Bscript::BObjectImp* UOExecutorModule::mf_RequestInput()
{
Mobile::Character* chr;
Items::Item* item;
const Bscript::String* prompt;
if ( !getCharacterParam( 0, chr ) || !getItemParam( 1, item ) || !getStringParam( 2, prompt ) )
{
return new Bscript::BError( "Invalid parameter" );
}
2016-02-11 22:54:43 +01:00
2018-07-31 14:30:29 +02:00
if ( chr->client == nullptr )
{
return new Bscript::BError( "No client attached" );
}
2016-02-11 22:54:43 +01:00
if ( chr->has_active_prompt() != false )
{
return new Bscript::BError( "Another script has an active prompt" );
}
2016-02-11 22:54:43 +01:00
if ( !uoexec().suspend() )
{
DEBUGLOGLN(
"Script Error in '{}' PC={}: \n"
"\tCall to function UO::RequestInput():\n"
"\tThe execution of this script can't be blocked!",
scriptname(), exec.PC );
return new Bscript::BError( "Script can't be blocked" );
}
if ( !prompt->hasUTF8Characters() )
{
Core::send_sysmessage( chr->client, prompt->data() );
chr->client->gd->prompt_uoemod = this;
prompt_chr = chr;
2016-02-11 22:54:43 +01:00
Core::send_prompt( chr->client, ctBEu32( item->serial ) );
}
else
{
Core::send_sysmessage_unicode( chr->client, prompt->value(), "ENU" );
2016-02-11 22:54:43 +01:00
chr->client->gd->prompt_uoemod = this;
prompt_chr = chr;
Core::send_unicode_prompt( chr->client, ctBEu32( item->serial ) );
}
return new Bscript::BLong( 0 );
}
2018-12-30 21:35:54 +01:00
} // namespace Module
} // namespace Pol