ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/cfplus.ext
Revision: 1.1
Committed: Fri Dec 15 19:29:18 2006 UTC (17 years, 5 months ago) by root
Branch: MAIN
Log Message:
moved perl extensions into server codebase, where they belong

File Contents

# User Rev Content
1 root 1.1 #! perl
2    
3     # additional support for cfplus client
4    
5     use NPC_Dialogue;
6    
7     =head1 CF+ protocol extensions
8    
9     This module implements protocol extensions for use by the CF+ client, but
10     can be used by other clients as well. It uses the C<extcmd> mechanism
11     exclusively.
12    
13     =over 4
14    
15     =item ... = extcmd cfplus_support { version => $client_version }
16    
17     Registers the client the the server. the client should send the highest
18     version of the protocol it supports itself, and the server returns the
19     highest version of the protocol it supports in the C<version> key itself.
20    
21     =cut
22    
23     cf::register_extcmd cfplus_support => sub {
24     my ($pl, $msg) = @_;
25    
26     # $msg->{version}
27    
28     (version => 2)
29     };
30    
31     my %dialog; # currently active dialogs
32    
33     my $timer = Event->timer (interval => 0.2, parked => 1, data => cf::WF_AUTOCANCEL, cb => sub {
34     while (my ($id, $dialog) = each %dialog) {
35     my (undef, $dx, $dy) = $dialog->{ob}->rangevector ($dialog->{npc});
36     next if (abs $dx) <= 2 && (abs $dy) <= 2;
37    
38     $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "out of range");
39     delete $dialog{$id};
40     }
41    
42     $_[0]->w->stop unless keys %dialog;
43     });
44    
45     sub dialog_tell {
46     my ($id, $dialog, $msg) = @_;
47    
48     my $pl = $dialog->{ob}->contr;
49     my ($reply, @kw) = $dialog->tell ($msg);
50     $reply = "..." unless $reply;
51    
52     $pl->ext_reply ($id => msgtype => "reply", msg => $reply, add_topics => \@kw);
53     }
54    
55     =item ... = extcmd lookat { dx => $dx, dy => $dy }
56    
57     "Looks at" the mapspace displaced (dx|dy) relative to the player
58     and returns "interesting" information about it.
59    
60     Keys it can return include:
61    
62     npc_dialog => $name
63     There is an npc or other object that can "talk" to the player.
64    
65     =cut
66    
67     cf::register_extcmd lookat => sub {
68     my ($pl, $msg) = @_;
69     my ($dx, $dy) = @$msg{qw(dx dy)};
70    
71     my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
72    
73     my %res;
74    
75     if ($pl->cell_visible ($dx, $dy)) {
76     for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
77     $res{npc_dialog} = $ob->name
78     if $near && NPC_Dialogue::has_dialogue $ob;
79     }
80     }
81    
82     %res
83     };
84    
85     =item ... = extcmd npc_dialog_begin { msgid => $id, dx => $dx, dy => $dy }
86    
87     Tries to start a dialogue with the mapspace specified by $dx and $dy (see
88     C<extcmd lookat>). The $msgid will be used as a handle for all future
89     messages related to this dialog interaction.
90    
91     It either replies with an error reply or starts a dialog by telling
92     the npc "hi" and returning a reply strcuture as with C<extcmd
93     npc_dialog_tell>.
94    
95     =cut
96    
97     cf::register_extcmd npc_dialog_begin => sub {
98     my ($pl, $msg) = @_;
99     my ($id, $dx, $dy) = @$msg{qw(msgid dx dy)};
100    
101     return unless (abs $dx) <= 2 && (abs $dy) <= 2;
102     return unless $pl->cell_visible ($dx, $dy);
103    
104     for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
105     if (NPC_Dialogue::has_dialogue $npc) {
106     $dialog{$id} = new NPC_Dialogue ob => $pl->ob, npc => $npc;
107     dialog_tell $id, $dialog{$id}, "hi";
108     $timer->start;
109     return;
110     }
111     }
112    
113     (msgtype => "error", msg => "nothing to talk to found")
114     };
115    
116     =item ... = extcmd npc_dialog_tell { msgid => $id, msg => $text }
117    
118     Tells the NPC the given $text message and returns a reply structure which
119     can have the following keys:
120    
121     msgtype => "reply"
122     msg => $reply_text,
123     add_topics => [additional topic strings]
124     del_topics => [invalidated topic strings]
125    
126     =cut
127    
128     cf::register_extcmd npc_dialog_tell => sub {
129     my ($pl, $msg) = @_;
130    
131     dialog_tell $msg->{msgid}, $dialog{$msg->{msgid}}, $msg->{msg}
132     if $dialog{$msg->{msgid}};
133    
134     ()
135     };
136    
137     =item extcmd npc_dialog_end { msgid => $id }
138    
139     Finishes the dialog, invalidating the handle.
140    
141     =cut
142    
143     cf::register_extcmd npc_dialog_end => sub {
144     my ($pl, $msg) = @_;
145    
146     delete $dialog{$msg->{msgid}};
147    
148     ()
149     };
150    
151     cf::attach_to_players
152     on_logout => sub {
153     my ($pl) = @_;
154    
155     delete $dialog{$_} for grep $pl->ob == $dialog{$_}{ob}, keys %dialog;
156     },
157     ;
158    
159     =item ... = extcmd editor_support
160    
161     Returns the value required by clients that have an editor to download and
162     upload maps from/to the server.
163    
164     servertype => (game|test) type of this server
165     gameserver => the hostname:port of the normal game server
166     testserver => the hostname:port of the test server the maps can be tested on
167     cvs_root => the (http) url where the cvs root for downloading is located
168     lib_root => the (http) url where crossfire.0 and archetypes can be found
169     upload => the (http) url where clients can upload maps
170    
171     If those values are not supplied or empty strings, the server does not
172     support downloading, uploading, testing, respectively.
173    
174     The upload script expects the following values in a multipart form upload:
175    
176     client: a descriptive string describing the editor and version used to upload
177     path: absolute server-side map path beginning with /
178     map: the map file itself
179     mapdir: the cvs root url originally used to download the map
180     revision: cvs-revision originally used to download the map
181     comment: a comment supplied by the user that documents the changes
182     cf_login: crossfire server login
183     cf_password: crossfire server password, optionally used for authentication purposes
184    
185     =cut
186    
187     cf::register_extcmd editor_support => sub {
188     my ($pl, $msg) = @_;
189    
190     map +($_ => $cf::CFG{"editor_$_"}), qw(servertype gameserver testserver cvs_root lib_root builder_ui)
191     };
192    
193     sub unload {
194     while (my ($id, $dialog) = each %dialog) {
195     $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "npc dialogue module was reloaded");
196     }
197    
198     %dialog = ();
199     }
200    
201     =back
202    
203     =cut
204