00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007 #include "mudconf.h"
00008 #include "externs.h"
00009 #include "powers.h"
00010 #include "rbtree.h"
00011 #include "debug.h"
00012
00013
00014 #define CHAN_NAME_LEN 50
00015
00016 struct history_message {
00017 time_t time;
00018 char *msg;
00019 struct history_message *next;
00020 };
00021
00022 struct channel {
00023 char name[50];
00024 int type;
00025 int charge;
00026 int owner;
00027 int amount_collected;
00028 int n_users;
00029 rbtree users;
00030 int channel_object;
00031 int n_history;
00032 struct history_message *history;
00033 };
00034
00035 struct channel_user {
00036 dbref player;
00037 char *title;
00038 char *alias;
00039 struct channel *channel;
00040 };
00041
00042 static rbtree channels = NULL;
00043 static rbtree channel_users = NULL;
00044
00045 static int comstar_compare_channel(void *vleft, void *vright, void *arg) {
00046 char *left = (char *)vleft;
00047 char *right= (char *)vright;
00048
00049 return strcmp(left, right);
00050 }
00051
00052 static int comstar_compare_channel_user(void *vleft, void *vright, void *arg) {
00053 int left = (int) vleft;
00054 int right = (int) vright;
00055
00056 return (left-right);
00057 }
00058
00059 static int comstar_compare_alias(void *vleft, void *vright, void *arg) {
00060 char *left = (char *)vleft;
00061 char *right = (char *)vright;
00062
00063 return strcasecmp(left, right);
00064 }
00065
00066 static void comstar_init(void) {
00067 channels = rb_init(comstar_compare_channel, NULL);
00068 channel_users = rb_init(comstar_compare_channel_user, NULL);
00069 }
00070
00071 static rbtree comstar_find_user_channels(dbref player) {
00072 rbtree uchan = NULL;
00073
00074 uchan = (rbtree) rb_find(channel_users, (void *)player);
00075 if(!uchan) {
00076 uchan = (rbtree) rb_init(comstar_compare_alias, NULL);
00077 rb_insert(channel_users, (void *)player, uchan);
00078 }
00079 return uchan;
00080 }
00081
00082 static struct channel *comstar_find_channel_by_name(char *name) {
00083 struct channel *channel = NULL;
00084
00085 channel = rb_find(channels, name);
00086 return channel;
00087 }
00088
00089 static struct channel *comstar_find_channel_by_user_alias(dbref player, char *alias) {
00090 rbtree uchan = NULL;
00091 struct channel_user *channel_user = NULL;
00092 struct channel *channel = NULL;
00093
00094 uchan = comstar_find_user_channels(player);
00095 if(!rb_exists(uchan, (void *)alias))
00096 return NULL;
00097
00098 channel_user = (struct channel_user *)rb_find(uchan, (void *)alias);
00099 return channel_user->channel;
00100 }
00101
00102 static int comstar_add_user_to_channel(char *name, char *alias, dbref player) {
00103 struct channel *channel = NULL;
00104 struct channel_user *channel_user = NULL;
00105 rbtree uchan = NULL;
00106
00107 channel = comstar_find_channel_by_name(name);
00108 if(!channel)
00109 return 0;
00110
00111 if(rb_exists(channel->users, (void *)player))
00112 return 0;
00113
00114 uchan = comstar_find_user_channels(player);
00115 if(!uchan)
00116 return 0;
00117
00118 if(rb_exists(uchan, (void *)alias))
00119 return 0;
00120
00121 channel_user = malloc(sizeof(struct channel_user));
00122 memset(channel_user, 0, sizeof(struct channel_user));
00123
00124 channel_user->player = player;
00125 channel_user->alias = strdup(alias);
00126 channel_user->channel = channel;
00127 channel_user->title = strdup("");
00128
00129 rb_insert(uchan, (void *)channel_user->alias, (void *)channel_user);
00130 rb_insert(channel->users, (void *)channel_user->player, (void *)channel_user);
00131 return 0;
00132 }
00133
00134
00135 static int comstar_remove_user_from_channel(char *name, dbref player) {
00136 struct channel *channel = NULL;
00137 struct channel_user *channel_user = NULL;
00138 rbtree uchan = NULL;
00139 channel = comstar_find_channel_by_name(name);
00140 if(!channel)
00141 return 0;
00142
00143 uchan = comstar_find_user_channels(player);
00144 if(!uchan)
00145 return 0;
00146
00147 channel_user = (struct channel_user *)rb_find(channel->users, (void *)player);
00148 if(!channel_user)
00149 return 0;
00150
00151 rb_delete(channel->users, (void *)player);
00152
00153 if(!channel_user->alias)
00154 return 0;
00155 rb_delete(uchan, (void *)channel_user->alias);
00156
00157 if(channel_user->title)
00158 free(channel_user->title);
00159 if(channel_user->alias)
00160 free(channel_user->alias);
00161
00162 memset(channel_user, 0, sizeof(struct channel_user));
00163 free(channel_user);
00164
00165 return 1;
00166 }
00167
00168 void do_createchannel(dbref player, dbref cause, int key, char *channame) {
00169 struct channel *newchannel = NULL;
00170
00171 if(!mudconf.have_comsys) {
00172 raw_notify(player, "Comsys disabled.");
00173 return;
00174 }
00175 if(comstar_find_channel_by_name(channame)) {
00176 notify_printf(player, "Channel %s already exists.", channame);
00177 return;
00178 }
00179 if(!channame || !*channame) {
00180 raw_notify(player, "You must specify a channel to create.");
00181 return;
00182 }
00183 if(!(Comm_All(player))) {
00184 raw_notify(player, "You do not have permission to do that.");
00185 return;
00186 }
00187 if(strlen(channame) > (CHAN_NAME_LEN-1)) {
00188 raw_notify(player, "Name too long.");
00189 return;
00190 }
00191 newchannel = (struct channel *) malloc(sizeof(struct channel));
00192 memset(newchannel, 0, sizeof(struct channel));
00193
00194 strncpy(newchannel->name, channame, CHAN_NAME_LEN - 1);
00195
00196 newchannel->type = 127;
00197 newchannel->owner = player;
00198 newchannel->channel_object = NOTHING;
00199 newchannel->users = rb_init(comstar_compare_channel_user, NULL);
00200 notify_printf(player, "Channel %s created.", channame);
00201 }
00202
00203 void do_destroychannel(dbref player, dbref cause, int key, char *channame) {
00204 struct channel *channel = NULL;
00205
00206 if(!mudconf.have_comsys) {
00207 raw_notify(player, "Comsys disabled.");
00208 return;
00209 }
00210 if(!channame || !*channame) {
00211 raw_notify(player, "No argument supplied.");
00212 return;
00213 }
00214 channel = comstar_find_channel_by_name(channame);
00215
00216 if(!channel) {
00217 notify_printf(player, "Could not find channel %s.", channel);
00218 return;
00219 } else if(!(Comm_All(player)) && (player != channel->owner)) {
00220 raw_notify(player, "You do not have permission to do that. ");
00221 return;
00222 }
00223 while(rb_size(channel->users) > 1) {
00224 struct channel_user *channel_user = NULL;
00225 channel_user = rb_search(channel->users, SEARCH_FIRST, NULL);
00226 if(!channel_user) break;
00227 if(!comstar_remove_user_from_channel(channel->name, channel_user->player))
00228 break;
00229 }
00230 rb_delete(channels, channame);
00231 memset(channel, 0, sizeof(struct channel));
00232 free(channel);
00233 }
00234
00235 void do_addcom(dbref player, dbref cause, int key, char *arg1, char *arg2) {
00236 struct channel *channel = NULL;
00237 if(!mudconf.have_comsys) {
00238 raw_notify(player, "Comsys disabled.");
00239 return;
00240 }
00241
00242 if(!arg1 || !*arg1) {
00243 raw_notify(player, "You need to specify an alias.");
00244 return;
00245 }
00246
00247 if(!arg2 || !*arg2) {
00248 raw_notify(player, "You need to specify a channel.");
00249 return;
00250 }
00251
00252 channel = comstar_find_channel_by_name(arg2);
00253 if(!channel) {
00254 raw_notify(player, "Sorry, Channel does not exist.");
00255 return;
00256 }
00257
00258 if(!comstar_add_user_to_channel(arg2, arg1, player)) {
00259 raw_notify(player, "Operation failed due to invalid argument.");
00260 return;
00261 }
00262 raw_notify(player, "Operation succeeded.");
00263 return;
00264 }
00265
00266 void do_delcom(dbref player, dbref cause, int key, char *arg1) {
00267 struct channel *channel = NULL;
00268
00269 if(!mudconf.have_comsys) {
00270 raw_notify(player, "Comsys disabled.");
00271 return;
00272 }
00273 if(!arg1 || !*arg1) {
00274 raw_notify(player, "Need an alias to delete.");
00275 return;
00276 }
00277
00278 channel = comstar_find_channel_by_user_alias(player, arg1);
00279 if(!channel) {
00280 raw_notify(player, "Channel alias does not exist.");
00281 return;
00282 }
00283
00284 if(!comstar_remove_user_from_channel(channel->name, player)) {
00285 raw_notify(player, "Operation failed due to invalid argument.");
00286 return;
00287 }
00288
00289 raw_notify(player, "Operation succeeded.");
00290 return;
00291 }
00292
00293