#include <lib.h>
#include <network.h>
#include <socket_err.h>
inherit LIB_ITEM;
static int counter = 0, attempting, connected, socket ;
static int dud_count = 0, spawning, last_action, loop_count = 0;
static int maxbox = 500;
static object person, player;
static string preset, name, passwd, gender;
static string display_name, email, real_name, race;
static string *exits, previous_command;
static string travel = "go ";
static int enable = 0;
//static string ip = "70.85.244.100 6502";
//static string ip = "192.168.0.3 4000";
//static string ip = "72.24.247.42 23";
static string ip = "192.168.0.68 5000";
//static string ip = "192.168.0.5 5050";
//static string ip = "192.168.0.6 7777";
//static string ip = "192.168.0.3 4000";
static string local_currency = "silver";
static string watching = "";
static int broadcast, onhand, open_account, balance, wander;
static int pocket_money = 600;
static int spent, in_combat;
static mixed *socks_array = ({});
int parse_comm( string str );
int DoorHandler(string str);
int do_connect(string args);
int do_reset( string args );
int Setup();
string eventBolo(string str);
string eventWatch(string str, string watching);
int eventCombatPrep();
static void create(mixed arg)
{
item::create();
if(arg && stringp(arg)) ip = arg;
SetKeyName("gamebot");
SetShort( "a gamebot" ) ;
SetId(({"bot","gamebot","module"}));
SetLong( "A gamebot control module.");
SetMass( 5 ) ;
attempting = 0 ;
connected = 0 ;
socket = 0 ;
person = 0 ;
parse_init();
set_heart_beat(0);
SetNoClean(1);
if(!name) name = alpha_crypt(random(10)+2);
if(!passwd) passwd = "password";
if(!gender) gender = "male";
if(!display_name) display_name = "Gamebot";
if(!email) email = "me@here";
if(!real_name) real_name = "John Smith";
if(!race) race = "human";
//if(clonep(this_object())) call_out( (: do_connect, ip :), 1);
//if(clonep(this_object())) call_out( (: Setup :), 60);
}
int eventBroadcastGreen(){
filter(all_inventory(environment()), (: $1 != this_object() :) )->eventStartBot(ip);
return 1;
}
int eventStartBot(string str){
if(attempting || connected) return 0;
if(str) ip = str;
set_heart_beat(1);
if(clonep(this_object())) call_out( (: do_connect, ip :), 1);
return 1;
}
int eventRespawn(){
object newbox;
string *file_names = ({});
int boxnum = 0;
if(!spent){
foreach(object thing in all_inventory(environment())){
if(base_name(thing) == base_name(this_object())){
boxnum++;
file_names += ({ file_name(thing) });
}
}
if(boxnum < maxbox){
newbox = new(base_name(this_object()));
newbox->eventMove(environment());
tell_object(environment(newbox), "Respawned box "+boxnum+": "+file_name(newbox));
}
}
spent = 1;
return 1;
}
int Setup(){
if(!enable){
dud_count++;
if(dud_count > 5){
if( socket )
{
socket_close( socket ) ;
}
tell_object(environment(),"I am "+name+" and I have failed. I die.");
parse_comm("dcon");
if(sizeof(filter(all_inventory(environment()), (: base_name($1) == base_name(this_object()) :) )) > 1) eventDestruct();
return 1;
}
do_reset("client");
do_connect(ip);
call_out( (: Setup :), 60);
}
return 1;
}
string random_act(){
string ret;
int randy = random(25);
switch(randy){
case 0 : ret = "inventory";break;
case 1 : ret = "score";break;
case 2 : ret = "who";break;
case 3 : ret = "stat";break;
case 4 : ret = "uptime";break;
case 5 : ret = "hist";break;
case 6 : ret = "env";break;
case 7 : ret = "money";break;
case 8 : ret = "hist newbie";break;
case 9 : ret = "hist gossip";break;
case 10 : ret = "mudlist";break;
case 11 : ret = "version";break;
case 12 : ret = "open door";break;
case 13 : ret = "cast buffer";break;
case 14 : ret = "cast meditate";break;
case 15 : ret = "search";break;
case 16 : ret = "put all in my bag";break;
case 17 : ret = "put all in my box";break;
case 18 : ret = "put all in my chest";break;
case 19 : ret = "wear all";break;
case 20 : ret = "wield first sword in right hand";break;
case 21 : ret = "wield first knife in right hand";break;
case 22 : ret = "wield first club in right hand";break;
case 23 : ret = "kill all";break;
case 24 : ret = "wimpy 30";break;
case 25 : in_combat = 0;ret = "look";break;
default : ret = "reply :)";break;
}
return ret;
}
string eventStargate(string str){
if(grepp(str,"idle stargate")){
int which = random(4);
switch(which){
case 0 : parse_comm("dial stargate lab");break;
case 1 : parse_comm("dial tower");break;
case 2 : parse_comm("dial campus lab");break;
case 3 : parse_comm("dial praxis");break;
default : parse_comm("dial praxis");break;
}
}
if(grepp(str,"outbound stargate")){
parse_comm("enter stargate");
}
return "wave";
}
int think(string str){
string ret = "";
int this_action = time();
this_object()->eventScanExits(str);
if(this_action - last_action > 10 && enable){
parse_comm("stand up");
in_combat = 0;
}
last_action = this_action;
if(enable) eventBolo(str);
if(sizeof(watching) < 1){
if(grepp(str, "You bump into ") && grepp(lower_case(str), "door")) DoorHandler(str);
if(grepp(str, "You stand up.")) travel = "go ";
if(grepp(str, "a portal forms")) ret = "enter portal";
if(grepp(str, "stargate is here")) ret = eventStargate(str);
if(grepp(str, "Perhaps you should try crawling.")) travel = "crawl ";
if(grepp(str, "What name do you wish")) ret = name;
if(grepp(str, "Please enter a new name:")) ret = name;
if(grepp(str, "Do you really wish to be known as ")) ret = "y";
if(grepp(str, "Create a password of at least 5 letters")) ret = passwd;
if(grepp(str, "Password:")) ret = passwd;
if(grepp(str, "Invalid password.")) ret = "12345";
if(grepp(str, "Please confirm your password")) ret = passwd;
if(grepp(str, "Please choose an interesting gender")) ret = gender;
if(grepp(str, "Please choose a gender")) ret = gender;
if(grepp(str, "to appear however you wish using spaces")) ret = name;
if(grepp(str, "requires a valid email")) ret = email;
if(grepp(str, "Type 'dcon' to finalize exit.")) ret = "dcon";
if(grepp(str, "If you do not mind, please enter your real name")) ret = real_name;
if(grepp(str, "You must now pick a race.")) ret = "pick "+race;
if(grepp(str, "No such race.")) ret = "pick roman";
if(grepp(str, "This mud has enabled AUTO_WIZ.")) ret = "player";
if(grepp(str, "Autosaving...")) ret = random_act();
if(grepp(str, "An interactive copy of you currently exists.")){
ret = "n";
name = alpha_crypt(14);
}
if(grepp(str, "No more attempts allowed")) ret = "foo";
if(grepp(str, "Reconnected.") || grepp(str,"You wear") ) {
ret = random_act();
enable = 1;
wander = 1;
}
if(grepp(str, "You may choose to regenerate into a new body here.")) ret = "regenerate";
if(grepp(str, "press enter:")) ret = "\n";
if(grepp(str, "%:")) ret = "\n";
previous_command = ret;
}
else {
ret = eventWatch(str, watching);
}
ret = trim(ret);
if(ret && ret != "" && sizeof(ret)) {
//tc("sizeof ret:"+sizeof(ret));
//tc(timestamp()+" in response to: "+str,"blue");
//tc(time()+"I am: "+identify(file_name(this_object()))+". I am sending: \""+ret+"\"\n");
this_object()->parse_comm(ret);
}
return 1;
}
string eventBolo(string str){
string ret = "\n";
wander = 0;
if(grepp(str, "press enter:") || grepp(str, "%:") ||
grepp(str,"Press <return> to continue:" )){
parse_comm("\n");
}
if(grepp(str, "table is here")){
parse_comm("get all from table");
}
if(grepp(str, "wardrobe")&& !grepp(str, "There is no ")) {
parse_comm("open first wardrobe");
parse_comm("get all from wardrobe chest");
parse_comm("wear all");
}
if(grepp(str, "chest")&& !grepp(str, "There is no ")) {
parse_comm("open first chest");
parse_comm("get all from first chest");
parse_comm("wear all");
}
if(grepp(str, "bag") && !grepp(str, "There is no ")){
parse_comm("open first bag");
parse_comm("get all from first bag");
parse_comm("wear all");
}
if(grepp(str, "box")&& !grepp(str, "There is no ")) {
parse_comm("open first box");
parse_comm("get all from first box");
parse_comm("wear all");
}
if(grepp(str, "a knife rack")){
parse_comm("get all from rack");
parse_comm("unwield all");
parse_comm("wield my first carving knife in right hand");
}
if(grepp(str, "You get") && (grepp(str, "flesh") || grepp(str, "corpse"))){
parse_comm("get all from my first corpse");
parse_comm("get all from my first pile");
}
if(grepp(str, "large stove")&& !grepp(str, "There is no ")){
parse_comm("open stove");
}
if(grepp(str, "You swing at")){
if(!in_combat){
eventCombatPrep();
}
}
if(grepp(str, " little rat ") ){
parse_comm("kill first rat");
}
if(grepp(str, "newt")){
parse_comm("kill first newt");
}
if(grepp(str, " orc") && ( grepp(str, "is standing here") || grepp(str, "are standing here")) ){
eventCombatPrep();
parse_comm("target first orc");
}
if(grepp(str, "Mansion Garden")) {
parse_comm("drop ladder");
parse_comm("climb ladder");
}
if(grepp(str, "Otik, the keeper of the shop")){
parse_comm("wear all");
parse_comm("unwield all");
parse_comm("sell all to otik");
parse_comm("buy sword from otik");
parse_comm("wield sword in right hand");
ret = "say Thank you, Otesanek.";
}
if(grepp(str,"You must create an account") ){
parse_comm("say ok, dude");
parse_comm("request account from zoe");
}
if(grepp(str, "Dirk the Tired")){
parse_comm("ask dirk to advance");
}
if(grepp(str, "Herkimer the kind wizard")){
parse_comm("ask herkimer to teach buffer");
parse_comm("ask herkimer to teach meditate");
}
if(grepp(str, "Zoe the bank teller")){
parse_comm("say hello, Zoe");
parse_comm("money");
parse_comm("ask zoe for balance");
if((onhand - pocket_money) > 0)
parse_comm("ask zoe to deposit "+(onhand - pocket_money)+" "+local_currency);
if(balance - pocket_money + onhand > 0 && (onhand + balance - 5) < pocket_money)
parse_comm("ask zoe to withdraw "+(pocket_money - onhand)+" "+local_currency);
}
if(grepp(str,"In your pockets you find only")){
string s1, s2;
int i1;
if(sscanf(str,"%s %d "+local_currency+"%s",s1,i1,s2) < 3)
onhand = 0;
else onhand = i1;
}
if(grepp(str, "and open an account with") ||
grepp(str,"You already have an account with") )
open_account = 1;
if(grepp(str, "Your last transaction:")){
string s1, s2, s3, s4;
int i1;
if(sscanf(str,"%s"+local_currency+"%s:%s\n%s",s1,s2,s3,s4) == 4){
balance = atoi(trim(s3));
}
}
wander = 1;
return ret;
}
void heart_beat(){
int bots;
counter++;
if(!environment(this_object())) return;
if(!clonep(this_object())) return;
bots = sizeof(filter(all_inventory(environment()),
(: base_name($1) == base_name(this_object()) :)));
if((!spent || bots < 2) && enable && bots < maxbox)
{
call_out( (: eventRespawn :), 2 );
}
if(!enable) return;
if(!(counter % 5)) this_object()->eventWalkabout();
if(!broadcast) eventBroadcastGreen();
if(!(counter % 20) && travel == "crawl ") parse_comm("stand up");
if(counter > 1000) counter = 0;
}
void init()
{
add_action( "do_connect", ({ "connect", "telnet" }) ) ;
add_action( "do_reset", "reset" ) ;
add_action( "do_reconnect", "reconnect" ) ;
add_action( "eventStartBot", "bot");
}
int DoorHandler(string str){
string s1;
if(!sscanf(str,"You bump into %s.",s1)) return 0;
parse_comm("unlock first door with first key");
parse_comm("unlock first door with second key");
parse_comm("open "+s1);
parse_comm("open first door");
return 1;
}
int eventScanExits(string str){
string s1, s2, s3;
string *oldexits = ({"go north","go south","go east","go west", "go up", "go down"});
string *newexits = ({});
string *dirs;
if(sscanf(str,"%s [%s]%s", s1, s2, s3) ){
dirs = explode(s2,",");
foreach(string dir in dirs){
dir = trim(dir);
switch(dir){
case "u" : dir = "up";break;
case "d" : dir = "down";break;
case "o" : dir = "out";break;
case "n" : dir = "north";break;
case "s" : dir = "south";break;
case "e" : dir = "east";break;
case "w" : dir = "west";break;
case "ne" : dir = "northeast";break;
case "nw" : dir = "northwest";break;
case "se" : dir = "southeast";break;
case "sw" : dir = "southwest";break;
}
if(grepp(dir,"enter ")) newexits += ({ dir });
else newexits += ({ travel+dir });
}
if(sizeof(newexits)) {
exits = newexits;
enable = 1;
}
}
if(!sizeof(exits)) exits = oldexits;
return 1;
}
int eventWalkabout(){
int randy = random(sizeof(exits));
if(in_combat) return 0;
parse_comm(exits[randy]);
parse_comm("get all");
return 1;
}
int eventCombatPrep(){
parse_comm("unwield all");
parse_comm("wear all");
parse_comm("wield first sword in right hand");
parse_comm("wield first knife in right hand");
parse_comm("wield first club in right hand");
parse_comm("wield first axe in right hand");
parse_comm("wield first dagger in right hand");
parse_comm("wield first staff in right hand and left hand");
parse_comm("wield first axe in right hand and left hand");
parse_comm("wear pack");
parse_comm("put all in bag");
parse_comm("put all in pack");
parse_comm("drop all");
in_combat = 1;
return 1;
}
void SetConnection(string str){
if(str) preset = str;
}
int do_reconnect()
{
if( !connected )
{
notify_fail( "The telnet client is not connected!\n" ) ;
return 0 ;
}
person = this_object() ;
return 1 ;
}
int do_reset( string args )
{
notify_fail( "Usage: reset client\n" ) ;
if( !args || args == "" )
{
return 0 ;
}
if( args != "client" )
{
return 0 ;
}
if( connected )
{
if( socket )
{
socket_close( socket ) ;
}
}
attempting = 0 ;
connected = 0 ;
socket = 0 ;
person = 0 ;
return 1 ;
}
int do_connect(string args)
{
int new_socket, sc_result, port ;
string error, ip_address ;
if( !args || args == "" )
{
notify_fail( "You fail." ) ;
return 0 ;
}
if( sscanf( args, "%s %d", ip_address, port ) != 2 )
{
notify_fail( "You fail." ) ;
return 0 ;
}
if( attempting )
{
notify_fail( "Telnet connection attempt already in progress.\n" ) ;
return 0 ;
}
if( connected )
{
notify_fail( "Already connected...\n" ) ;
return 0 ;
}
new_socket = socket_create( STREAM, "read_callback", "close_callback" ) ;
write("new_socket: "+new_socket);
loop_count++;
if(loop_count > 10) this_object()->eventDestruct();
foreach(mixed element in socket_status()){
if(intp(element[0]) && element[0] != -1 && !grepp(element[3],"*")){
socks_array += element[0];
}
}
socks_array = ({});
if( new_socket < 0 )
{
switch( new_socket )
{
case EEMODENOTSUPP :
error = "Socket mode not supported.\n" ;
break ;
case EESOCKET :
error = "Problem creating socket.\n" ;
break ;
case EESETSOCKOPT :
error = "Problem with setsockopt.\n" ;
break ;
case EENONBLOCK :
error = "Problem with setting non-blocking mode.\n" ;
break ;
case EENOSOCKS :
error = "No more available efun sockets.\n" ;
break ;
case EESECURITY :
error = "Security violation attempted.\n" ;
break ;
default :
error = "Unknown error code: " + new_socket + ".\n" ;
break ;
}
notify_fail( "Unable to connect, problem with socket_create.\n"
"Reason: " + error ) ;
return 0 ;
}
sc_result = socket_connect( new_socket, ip_address + " " + port,
"read_callback", "write_callback" ) ;
if( sc_result != EESUCCESS )
{
notify_fail( "Failed to connect.\n" ) ;
return 0 ;
}
attempting = 1 ;
socket = new_socket ;
person = (object)previous_object() ;
player=this_object();
//tc("stack: "+get_stack());
tell_object(environment(),"I am "+name+", a.k.a "+file_name(this_object())+
" and I am connected to "+ip+" on socket"+socket+"\n");
spent = 0;
return 1 ;
}
void read_callback( int fd, mixed message )
{
player->eventPrint(message);
player->think(message);
}
void close_callback( int fd )
{
if( connected )
{
}
if( attempting )
{
}
socket_close( fd ) ;
attempting = 0 ;
connected = 0 ;
socket = 0 ;
}
void write_callback( int fd )
{
attempting = 0 ;
connected = 1 ;
}
int parse_comm( string str )
{
//tc("hit parse comm with: \""+str+"\", size is: "+sizeof(str),"red");
if(str=="dcon" || str=="quit")
{
socket_close( socket ) ;
attempting = 0 ;
connected = 0 ;
socket = 0 ;
person = 0 ;
this_object()->eventDescribeEnvironment();
return 1 ;
} else {
if( !connected )
{
int fco;
enable = 0;
fco = find_call_out("Setup");
if(fco == -1) Setup();
return 1 ;
}
if( attempting )
{
int fco;
enable = 0;
fco = find_call_out("Setup");
if(fco == -1) Setup();
return 1 ;
}
socket_write( socket, str + "\n" ) ;
return 1 ;
}
}