Pol  Revision:cb584c9
partymod.cpp
Go to the documentation of this file.
1 
8 #include "pol_global_config.h"
9 
10 #include "partymod.h"
11 
12 #include <stddef.h>
13 
14 #include "../../bscript/berror.h"
15 #include "../../bscript/bobject.h"
16 #include "../../bscript/executor.h"
17 #include "../../bscript/objmembers.h"
18 #include "../../bscript/objmethods.h"
19 #include "../../clib/compilerspecifics.h"
20 #include "../../clib/rawtypes.h"
21 #include "../clfunc.h"
22 #include "../fnsearch.h"
23 #include "../globals/settings.h"
24 #include "../globals/uvars.h"
25 #include "../mobile/charactr.h"
26 #include "../party.h"
27 #include "../party_cfg.h"
28 #include "../pktdef.h"
29 #include "../syshook.h"
30 #include "../unicode.h"
31 #include "../uoexhelp.h"
32 #include "../uoscrobj.h"
33 
34 namespace Pol
35 {
36 namespace Bscript
37 {
38 using namespace Module;
39 template <>
42  {"CreateParty", &PartyExecutorModule::mf_CreateParty},
43  {"DisbandParty", &PartyExecutorModule::mf_DisbandParty},
44  {"SendPartyMsg", &PartyExecutorModule::mf_SendPartyMsg},
45  {"SendPrivatePartyMsg", &PartyExecutorModule::mf_SendPrivatePartyMsg},
46 };
47 }
48 namespace Module
49 {
50 using namespace Bscript;
51 
53  : TmplExecutorModule<PartyExecutorModule>( "Party", exec )
54 {
55 }
56 
57 class EPartyRefObjImp : public BApplicObj<Core::PartyRef>
58 {
59 public:
61  virtual const char* typeOf() const POL_OVERRIDE;
62  virtual u8 typeOfInt() const POL_OVERRIDE;
63  virtual BObjectImp* copy() const POL_OVERRIDE;
64  virtual bool isTrue() const POL_OVERRIDE;
65  virtual bool operator==( const BObjectImp& objimp ) const POL_OVERRIDE;
66 
67  virtual BObjectRef get_member( const char* membername ) POL_OVERRIDE;
68  virtual BObjectRef get_member_id( const int id ) POL_OVERRIDE; // id test
69  virtual BObjectImp* call_method( const char* methodname, Executor& ex ) POL_OVERRIDE;
70  virtual BObjectImp* call_method_id( const int id, Executor& ex,
71  bool forcebuiltin = false ) POL_OVERRIDE;
72 };
75  : BApplicObj<Core::PartyRef>( &party_type, pref ){};
76 
77 const char* EPartyRefObjImp::typeOf() const
78 {
79  return "PartyRef";
80 }
82 {
83  return OTPartyRef;
84 }
85 
87 {
88  return new EPartyRefObjImp( obj_ );
89 }
90 
92 {
93  return ( obj_->test_size() );
94 }
95 
96 bool EPartyRefObjImp::operator==( const BObjectImp& objimp ) const
97 {
98  if ( objimp.isa( BObjectImp::OTApplicObj ) )
99  {
100  const BApplicObjBase* aob =
101  Clib::explicit_cast<const BApplicObjBase*, const BObjectImp*>( &objimp );
102 
103  if ( aob->object_type() == &party_type )
104  {
105  const EPartyRefObjImp* partyref_imp =
106  Clib::explicit_cast<const EPartyRefObjImp*, const BApplicObjBase*>( aob );
107 
108  return ( partyref_imp->obj_->leader() == obj_->leader() );
109  }
110  else
111  return false;
112  }
113  else if ( objimp.isa( Bscript::BObjectImp::OTBoolean ) )
114  return isTrue() == static_cast<const Bscript::BBoolean&>( objimp ).isTrue();
115  else
116  return false;
117 }
118 
120 {
121  return new EPartyRefObjImp( ref_ptr<Core::Party>( party ) );
122 }
123 
124 BObjectRef EPartyRefObjImp::get_member( const char* membername )
125 {
126  ObjMember* objmember = getKnownObjMember( membername );
127  if ( objmember != nullptr )
128  return this->get_member_id( objmember->id );
129  else
130  return BObjectRef( UninitObject::create() );
131 }
132 
133 BObjectRef EPartyRefObjImp::get_member_id( const int id ) // id test
134 {
135  switch ( id )
136  {
137  case MBR_MEMBERS:
138  {
139  std::unique_ptr<ObjArray> arr( new ObjArray );
140  auto itr = obj_->_member_serials.begin();
141  while ( itr != obj_->_member_serials.end() )
142  {
144  if ( chr != nullptr )
145  {
146  arr->addElement( new EOfflineCharacterRefObjImp( chr ) );
147  ++itr;
148  }
149  else
150  itr = obj_->_member_serials.erase( itr );
151  }
152  return BObjectRef( arr.release() );
153  }
154 
155  case MBR_LEADER:
156  {
157  Mobile::Character* chr = Core::system_find_mobile( obj_->_leaderserial );
158  if ( chr != nullptr )
159  return BObjectRef( new EOfflineCharacterRefObjImp( chr ) );
160  else
161  return BObjectRef( new BLong( 0 ) );
162  }
163 
164  case MBR_CANDIDATES:
165  {
166  std::unique_ptr<ObjArray> arr( new ObjArray );
167  auto itr = obj_->_candidates_serials.begin();
168  while ( itr != obj_->_candidates_serials.end() )
169  {
171  if ( chr != nullptr )
172  {
173  arr->addElement( new EOfflineCharacterRefObjImp( chr ) );
174  ++itr;
175  }
176  else
177  itr = obj_->_candidates_serials.erase( itr );
178  }
179  return BObjectRef( arr.release() );
180  }
181 
182  default:
183  return BObjectRef( UninitObject::create() );
184  }
185 }
186 
187 BObjectImp* EPartyRefObjImp::call_method( const char* methodname, Executor& ex )
188 {
189  ObjMethod* objmethod = getKnownObjMethod( methodname );
190  if ( objmethod != nullptr )
191  return this->call_method_id( objmethod->id, ex );
192  else
193  {
194  bool changed = false;
195  return CallPropertyListMethod( obj_->_proplist, methodname, ex, changed );
196  }
197 }
198 
199 BObjectImp* EPartyRefObjImp::call_method_id( const int id, Executor& ex, bool /*forcebuiltin*/ )
200 {
201  switch ( id )
202  {
203  case MTH_ADDMEMBER:
204  {
205  Mobile::Character* chr;
206  if ( !ex.hasParams( 1 ) )
207  return new BError( "Not enough parameters" );
208  if ( !getCharacterParam( ex, 0, chr ) )
209  return new BError( "Invalid parameter type" );
210  if ( chr->has_party() )
211  return new BError( "Character is already in a party" );
212  else if ( chr->has_candidate_of() )
213  return new BError( "Character is already candidate of a party" );
214  else if ( chr->has_offline_mem_of() )
215  return new BError( "Character is already offline member of a party" );
216  if ( !obj_->can_add() )
217  return new BError( "Party is already full" );
218  if ( obj_->add_member( chr->serial ) )
219  {
220  chr->party( obj_.get() );
221  if ( Core::settingsManager.party_cfg.Hooks.OnAddToParty )
223  if ( chr->has_active_client() )
225  Core::CLP_Added ); // You have been added to the party.
226  obj_->send_msg_to_all( Core::CLP_Joined, chr->name().c_str(), chr ); // : joined the party.
227  obj_->send_member_list( nullptr );
228  obj_->send_stats_on_add( chr );
229  }
230 
231  return new BLong( static_cast<int>( obj_->_member_serials.size() ) );
232  }
233 
234  case MTH_REMOVEMEMBER:
235  {
236  Mobile::Character* chr;
237  if ( !ex.hasParams( 1 ) )
238  return new BError( "Not enough parameters" );
239  if ( !getCharacterParam( ex, 0, chr ) )
240  return new BError( "Invalid parameter type" );
241  if ( !obj_->is_member( chr->serial ) )
242  return new BError( "Character is not in this party" );
243  if ( obj_->is_leader( chr->serial ) )
244  return new BError( "Character is leader of this party" );
245 
246  if ( obj_->remove_member( chr->serial ) )
247  {
248  bool disband;
249  obj_->send_remove_member( chr, &disband );
250  chr->party( nullptr );
251  if ( Core::settingsManager.party_cfg.Hooks.OnLeaveParty )
253  if ( chr->has_active_client() )
254  {
256  Core::CLP_Removed ); // You have been removed from the party.
257  Core::send_empty_party( chr );
258  }
259  if ( disband )
260  Core::disband_party( obj_->leader() );
261 
262  return new BLong( 1 );
263  }
264  return new BLong( 0 );
265  }
266 
267  case MTH_SETLEADER:
268  {
269  Mobile::Character* chr;
270  if ( !ex.hasParams( 1 ) )
271  return new BError( "Not enough parameters" );
272  if ( !getCharacterParam( ex, 0, chr ) )
273  return new BError( "Invalid parameter type" );
274  if ( !obj_->is_member( chr->serial ) )
275  return new BError( "Character is not in this party" );
276  if ( obj_->is_leader( chr->serial ) )
277  return new BError( "Character is already leader of this party" );
278 
279  obj_->set_leader( chr->serial );
280  obj_->send_member_list( nullptr );
281  return new BLong( 1 );
282  }
283 
284  case MTH_ADDCANDIDATE:
285  {
286  Mobile::Character* chr;
287  if ( !ex.hasParams( 1 ) )
288  return new BError( "Not enough parameters" );
289  if ( !getCharacterParam( ex, 0, chr ) )
290  return new BError( "Invalid parameter type" );
291  if ( chr->has_party() )
292  return new BError( "Character is already in a party" );
293  else if ( chr->has_candidate_of() )
294  return new BError( "Character is already candidate of a party" );
295  else if ( chr->has_offline_mem_of() )
296  return new BError( "Character is already offline member of a party" );
297  if ( !obj_->can_add() )
298  return new BError( "Party is already full" );
299  if ( !chr->has_active_client() )
300  return new BError( "Character is offline" );
301 
302  if ( Core::settingsManager.party_cfg.General.DeclineTimeout > 0 )
304 
305  if ( obj_->add_candidate( chr->serial ) )
306  {
307  Mobile::Character* leader = Core::system_find_mobile( obj_->leader() );
308  if ( leader != nullptr )
309  {
310  chr->candidate_of( obj_.get() );
311  Core::send_invite( chr, leader );
312  return new BLong( 1 );
313  }
314  }
315  return new BLong( 0 );
316  }
317 
318  case MTH_REMOVECANDIDATE:
319  {
320  Mobile::Character* chr;
321  if ( !ex.hasParams( 1 ) )
322  return new BError( "Not enough parameters" );
323  if ( !getCharacterParam( ex, 0, chr ) )
324  return new BError( "Invalid parameter type" );
325  if ( !obj_->is_candidate( chr->serial ) )
326  return new BError( "Character is not candidate of this party" );
327 
328  if ( obj_->remove_candidate( chr->serial ) )
329  {
331  Mobile::Character* leader = Core::system_find_mobile( obj_->leader() );
332  chr->candidate_of( nullptr );
333  if ( chr->has_active_client() )
335  chr->client,
336  Core::CLP_Decline ); // You notify them that you do not wish to join the party.
337  if ( leader != nullptr )
338  {
339  if ( leader->has_active_client() )
341  chr->name().c_str(),
342  true ); //: Does not wish to join the party.
343  }
344 
345  if ( !obj_->test_size() )
346  Core::disband_party( obj_->leader() );
347  return new BLong( 1 );
348  }
349  return new BLong( 0 );
350  }
351 
352  default:
353  bool changed = false;
354  return CallPropertyListMethod_id( obj_->_proplist, id, ex, changed );
355  }
356 }
357 
358 // party.em Functions:
359 bool getPartyParam( Executor& exec, unsigned param, Core::Party*& party, BError*& err )
360 {
361  BApplicObjBase* aob = nullptr;
362  if ( exec.hasParams( param + 1 ) )
363  aob = exec.getApplicObjParam( param, &party_type );
364 
365  if ( aob == nullptr )
366  {
367  err = new BError( "Invalid parameter type" );
368  return false;
369  }
370 
371  EPartyRefObjImp* pr = static_cast<EPartyRefObjImp*>( aob );
372  party = pr->value().get();
373  if ( Core::system_find_mobile( party->leader() ) == nullptr )
374  {
375  err = new BError( "Party has no leader" );
376  return false;
377  }
378  return true;
379 }
380 
382 {
383  Mobile::Character* leader;
384  Mobile::Character* firstmem;
385  if ( ( getCharacterParam( exec, 0, leader ) ) && ( getCharacterParam( exec, 1, firstmem ) ) )
386  {
387  if ( leader->has_party() )
388  return new BError( "Leader is already in a party" );
389  else if ( leader->has_candidate_of() )
390  return new BError( "Leader is already candidate of a party" );
391  else if ( leader->has_offline_mem_of() )
392  return new BError( "Leader is already offline member of a party" );
393  else if ( leader == firstmem )
394  return new BError( "Leader and Firstmember are the same" );
395  else if ( firstmem->has_party() )
396  return new BError( "First Member is already in a party" );
397  else if ( firstmem->has_candidate_of() )
398  return new BError( "First Member is already candidate of a party" );
399  else if ( firstmem->has_offline_mem_of() )
400  return new BError( "First Member is already offline member of a party" );
401 
402  Core::Party* party = new Core::Party( leader->serial );
403  Core::gamestate.parties.push_back( ref_ptr<Core::Party>( party ) );
404  leader->party( party );
405 
406  if ( party->add_member( firstmem->serial ) )
407  {
408  firstmem->party( party );
409  if ( Core::settingsManager.party_cfg.Hooks.OnPartyCreate )
411  party->send_msg_to_all( Core::CLP_Added ); // You have been added to the party.
412  if ( leader->has_active_client() )
413  Core::send_sysmessage_cl_affix( leader->client, Core::CLP_Joined, firstmem->name().c_str(),
414  true ); // : joined the party.
415  if ( firstmem->has_active_client() )
416  Core::send_sysmessage_cl_affix( firstmem->client, Core::CLP_Joined, leader->name().c_str(),
417  true );
418  party->send_member_list( nullptr );
419  party->send_stats_on_add( firstmem );
420  }
421 
422  return new BLong( 1 );
423  }
424  else
425  return new BError( "Invalid parameter type" );
426 }
427 
429 {
430  Core::Party* party;
431  BError* err;
432  if ( getPartyParam( exec, 0, party, err ) )
433  {
434  Core::disband_party( party->leader() );
435  return new BLong( 1 );
436  }
437  else
438  return err;
439 }
440 
442 {
443  Core::Party* party;
444  BError* err;
445  if ( getPartyParam( exec, 0, party, err ) )
446  {
447  ObjArray* oText;
448  Mobile::Character* chr;
449  if ( ( getCharacterParam( exec, 1, chr ) ) && ( getObjArrayParam( 2, oText ) ) )
450  {
451  size_t textlen = oText->ref_arr.size();
452  u16 gwtext[( SPEECH_MAX_LEN + 1 )];
453  if ( textlen > SPEECH_MAX_LEN )
454  return new BError( "Unicode array exceeds maximum size." );
455  if ( !Core::convertArrayToUC( oText, gwtext, textlen, true ) )
456  return new BError( "Invalid value in Unicode array." );
457 
458  if ( Core::settingsManager.party_cfg.Hooks.OnPublicChat )
460 
461  party->send_member_msg_public( chr, gwtext, textlen );
462  return new BLong( 1 );
463  }
464  else
465  return new BError( "Invalid parameter type" );
466  }
467  else
468  return err;
469 }
470 
472 {
473  Core::Party* party;
474  BError* err;
475  if ( getPartyParam( exec, 0, party, err ) )
476  {
477  ObjArray* oText;
478  Mobile::Character* chr;
479  Mobile::Character* tochr;
480  if ( ( getCharacterParam( exec, 1, chr ) ) && ( getCharacterParam( exec, 2, tochr ) ) &&
481  ( getObjArrayParam( 3, oText ) ) )
482  {
483  size_t textlen = oText->ref_arr.size();
484  u16 gwtext[( SPEECH_MAX_LEN + 1 )];
485  if ( textlen > SPEECH_MAX_LEN )
486  return new BError( "Unicode array exceeds maximum size." );
487  if ( !Core::convertArrayToUC( oText, gwtext, textlen, true ) )
488  return new BError( "Invalid value in Unicode array." );
489 
490  if ( Core::settingsManager.party_cfg.Hooks.OnPrivateChat )
492  tochr->make_ref(), oText );
493 
494  party->send_member_msg_private( chr, tochr, gwtext, textlen );
495  return new BLong( 1 );
496  }
497  else
498  return new BError( "Invalid parameter type" );
499  }
500  else
501  return err;
502 }
503 }
504 }
unsigned char u8
Definition: rawtypes.h:25
void cancel_party_invite_timeout()
Definition: party.cpp:1520
virtual const char * typeOf() const POL_OVERRIDE
Definition: partymod.cpp:77
void set_party_invite_timeout()
Definition: party.cpp:1502
struct Pol::Core::Party_Cfg::@14 Hooks
void send_sysmessage_cl(Client *client, unsigned int cliloc_num, const u16 *arguments, unsigned short font, unsigned short color)
Definition: clfunc.cpp:26
Bscript::BObjectImp * mf_SendPartyMsg()
Definition: partymod.cpp:441
#define POL_OVERRIDE
u16 gwtext[(SPEECH_MAX_LEN+1)]
Definition: unimod.cpp:140
ExportedFunction * OnPartyCreate
Definition: party_cfg.h:43
bool call(Bscript::BObjectImp *p0)
Definition: syshook.cpp:44
bool isa(BObjectType type) const
Definition: bobject.h:353
Network::Client * client
Definition: charactr.h:871
const int CLP_Added
Definition: party_cfg.h:55
T * get() const
Definition: refptr.h:176
ObjMember * getKnownObjMember(const char *token)
Definition: parser.cpp:483
#define SPEECH_MAX_LEN
Definition: pktdef.h:27
BObjectImp * CreatePartyRefObjImp(Core::Party *party)
Definition: partymod.cpp:119
bool operator==(T *ptr, const ref_ptr< T > &rptr)
Definition: refptr.h:311
virtual BObjectImp * call_method(const char *methodname, Executor &ex) POL_OVERRIDE
Definition: partymod.cpp:187
EPartyRefObjImp(Core::PartyRef pref)
Definition: partymod.cpp:74
bool has_active_client() const
Definition: charactr.cpp:448
PartyExecutorModule(Bscript::Executor &exec)
Definition: partymod.cpp:52
ExportedFunction * OnAddToParty
Definition: party_cfg.h:38
u32 leader() const
Definition: party.cpp:276
Bscript::BObjectImp * mf_SendPrivatePartyMsg()
Definition: partymod.cpp:471
void send_msg_to_all(unsigned int clilocnr, const char *affix=0, Mobile::Character *exeptchr=nullptr) const
Definition: party.cpp:547
const int CLP_Notify_Decline
Definition: party_cfg.h:73
ObjMethod * getKnownObjMethod(const char *token)
Definition: parser.cpp:666
const BApplicObjType * object_type() const
Definition: bobject.h:897
unsigned short u16
Definition: rawtypes.h:26
bool getCharacterParam(Bscript::Executor &exec, unsigned param, Mobile::Character *&chrptr)
Definition: uoexhelp.cpp:140
Bscript::BObjectImp * CallPropertyListMethod_id(PropertyList &proplist, const int id, Bscript::Executor &ex, bool &changed)
Definition: proplist.cpp:520
void send_empty_party(Mobile::Character *chr)
Definition: party.cpp:795
virtual BObjectImp * copy() const POL_OVERRIDE
Definition: partymod.cpp:86
virtual BObjectRef get_member(const char *membername) POL_OVERRIDE
Definition: partymod.cpp:124
bool getPartyParam(Executor &exec, unsigned param, Core::Party *&party, BError *&err)
Definition: partymod.cpp:359
const int CLP_Removed
Definition: party_cfg.h:63
void disband_party(u32 leader)
Definition: party.cpp:824
Definition: refptr.h:65
BApplicObjType party_type
Definition: partymod.cpp:73
ExportedFunction * OnPublicChat
Definition: party_cfg.h:45
bool convertArrayToUC(Bscript::ObjArray *&in_text, u16 *out_wtext, size_t textlen, bool ConvToBE, bool nullterm)
Definition: unicode.cpp:21
Parties parties
Definition: uvars.h:158
static UninitObject * create()
Definition: bobject.h:482
ExportedFunction * OnLeaveParty
Definition: party_cfg.h:41
const int CLP_Decline
Definition: party_cfg.h:74
virtual Bscript::BObjectImp * make_ref() POL_OVERRIDE
Definition: uoscrobj.cpp:1650
GameState gamestate
Definition: uvars.cpp:74
virtual BObjectImp * call_method_id(const int id, Executor &ex, bool forcebuiltin=false) POL_OVERRIDE
Definition: partymod.cpp:199
Bscript::BObjectImp * mf_CreateParty()
Definition: partymod.cpp:381
SettingsManager settingsManager
Definition: settings.cpp:14
void send_member_msg_public(Mobile::Character *chr, u16 *wtext, size_t wtextlen) const
Definition: party.cpp:671
Mobile::Character * system_find_mobile(u32 serial)
Definition: fnsearch.cpp:32
Bscript::BObjectImp * mf_DisbandParty()
Definition: partymod.cpp:428
BApplicObjBase * getApplicObjParam(unsigned param, const BApplicObjType *object_type)
Definition: executor.cpp:488
virtual u8 typeOfInt() const POL_OVERRIDE
Definition: partymod.cpp:81
void send_sysmessage_cl_affix(Client *client, unsigned int cliloc_num, const char *affix, bool prepend, const u16 *arguments, unsigned short font, unsigned short color)
Definition: clfunc.cpp:128
const int CLP_Joined
Definition: party_cfg.h:75
void send_member_list(Mobile::Character *to_chr)
Definition: party.cpp:415
D explicit_cast(const S &s)
Definition: stlutil.h:40
bool hasParams(unsigned howmany) const
Definition: executor.h:144
Bscript::BObjectImp * CallPropertyListMethod(PropertyList &proplist, const char *methodname, Bscript::Executor &ex, bool &changed)
Definition: proplist.cpp:591
ExportedFunction * OnPrivateChat
Definition: party_cfg.h:44
void send_stats_on_add(Mobile::Character *newmember) const
Definition: party.cpp:588
virtual std::string name() const
Definition: uobject.cpp:196
bool add_member(u32 serial)
Definition: party.cpp:338
virtual bool isTrue() const POL_OVERRIDE
Definition: partymod.cpp:91
Definition: berror.cpp:12
void send_member_msg_private(Mobile::Character *chr, Mobile::Character *tochr, u16 *wtext, size_t wtextlen) const
Definition: party.cpp:718
virtual BObjectRef get_member_id(const int id) POL_OVERRIDE
Definition: partymod.cpp:133
virtual bool operator==(const BObjectImp &objimp) const POL_OVERRIDE
Definition: partymod.cpp:96
void send_invite(Mobile::Character *member, Mobile::Character *leader)
Definition: party.cpp:1438