File: LoginPerson.pm

package info (click to toggle)
perlmoo 0.045
  • links: PTS
  • area: main
  • in suites: slink
  • size: 404 kB
  • ctags: 242
  • sloc: perl: 5,211; makefile: 111; sh: 77
file content (164 lines) | stat: -rw-r--r-- 3,672 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# A special restricted person that is used only before a user properly logs
# into the moo, to prompt for their login name and password.

package LoginPerson;
use strict;
use vars qw(@ISA);
use Thing;
use Verb;
use VerbCall;
use ThingList;
use Error;
use UNIVERSAL qw(isa);
@ISA=qw{Thing};

sub new {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	
	# I pass in all these values because LoginPeople arn't dumped out
	# so they don't get any inheritance done on them, so we have to
	# duplicate some data.
	my $this  = Thing::new($class,
		# No reason to dump this type of object.
		nodump => 1,
		location => undef,
		connected => undef,
		output_callback => sub {},
		close_callback => sub {},
		fertile => undef,
		
		# Remove all verbs already set.
		verbs => {},
		
		help_msg => "I don't understand that. Valid commands at this point are:\r\n\tconnect\r\n\tquit",

		host => undef,

		@_
	);

	$this->perms_r('output_callback',1);
	$this->perms_r('close_callback',1);
	$this->perms_r('host',1);
	
	$this->addverb(Verb->new(
		sub => 'verb_connect',
		command => 'co*nnect',
		direct_object => 'any',
		preposition => 'any',
	));
	$this->addverb(Verb->new(
		sub => 'verb_connect',
		command => 'logi*n',
		direct_object => 'any',
		preposition => 'any',
	));
	$this->addverb(Verb->new(
		sub => 'verb_logout',
		command => 'logo*ut',
	));
	$this->addverb(Verb->new(
		sub => 'verb_logout',
		command => 'quit',
	));

	bless ($this, $class);
	return $this;
}

# Outputs a collection of text to the user.
# Each seperate item is taken to be a new line.
sub tell {
	my $this=shift;
	
	foreach (@_) {
		# Need to print out any errors that filtered down to here.
		if (Error::iserror($_)) {
			&{$this->output_callback}($_->message."\r\n");
		}
		elsif ($_) {
			&{$this->output_callback}("$_\r\n");
		}						
	}
}

# Takes a line of input from the remote user, parses it, and executes it.
sub parse {
	my $this=shift;
	my $line=shift;

	$line=~s/[\r\n]//g; # have to handle both types of line endings.

	my @words=Text::SplitWords($line);

	my $verbcall=VerbCall->new();
	$verbcall->caller($this);
	$verbcall->words(@words);
	$verbcall->command($line);

	# Test for the verb being implmented, on this object only.
	my $sub=$this->getverbsub($verbcall);
	if (defined $sub) {
		return $this->$sub($verbcall);
	}

	return Text::subst($this->help_msg);
}

# Override the location method so that whenever a loginperson moves somewhere,
# they are shown the new location.
sub location {
	my $this=shift;
	if (@_) {
		my $newloc=shift;
		if ($newloc && Thing::location($this) != $newloc) {
			Thing::location($this,$newloc);
			$this->tell($newloc->look);
		}
	}
	
	return Thing::location($this);
}

# On logout, we delete outselves.
sub logout {
	my $this=shift;
	Utils::SuWizard(); # TODO: needed, but why?
	$this->remove;
}

# This is responsible for authenticating the user into the moo.
sub verb_connect {
	my $this=shift;
	my $verbcall=shift;
	
	# Figure out what person matches the name.
	my @words=$verbcall->words;
	my $user=ThingList::FindByName($words[1],"Person");
	
	# Now ask the person if the provided credentials are sufficient for
	# login.
	if ($user && $user->login($this,@words)) {
		# Now we're done - the login method of a person handles
		# all the setup. All that's left to do is remove outselves.
		$this->remove;
		return;
	}
	else {
		return Error->new("Login failure.");
	}
}

# This disconnects them in case they changed their mind or something.
sub verb_logout {
	my $this=shift;
	my $verbcall=shift;

	&{$this->close_callback};
#	$this->location->contents_remove($this);
	Utils::SuWizard(); # TODO: needed, but why?
	$this->remove;
}

1