001: /*- ChannelManager.java -------------------------------------------+
002: | |
003: | Copyright (C) 2002-2003 Joseph Monti, LlamaChat |
004: | countjoe@users.sourceforge.net |
005: | http://www.42llamas.com/LlamaChat/ |
006: | |
007: | This program is free software; you can redistribute it and/or |
008: | modify it under the terms of the GNU General Public License |
009: | as published by the Free Software Foundation; either version 2 |
010: | of the License, or (at your option) any later version |
011: | |
012: | This program is distributed in the hope that it will be useful, |
013: | but WITHOUT ANY WARRANTY; without even the implied warranty of |
014: | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
015: | GNU General Public License for more details. |
016: | |
017: | A copy of the GNU General Public License may be found in the |
018: | installation directory named "GNUGPL.txt" |
019: | |
020: +-----------------------------------------------------------------+
021: */
022:
023: package server;
024:
025: import java.util.Vector;
026: import java.util.Hashtable;
027: import java.util.Enumeration;
028:
029: /* -------------------- JavaDoc Information ----------------------*/
030: /**
031: * This class manages the channels for the server. It allows 3 types
032: * of channels. The first of which, defaultChannel, is limited to
033: * one and is the default channel that users are sent to when
034: * connecting. The second, systemChannels, is a collection of channels
035: * that are perminent and created upon program initialization from
036: * the configuration file. The third, userChannels, are created by users
037: * and can only exist if specified in the system configuration file. When
038: * a userChannel is empty it is deleted.
039: * @author Joseph Monti <a href="mailto:countjoe@users.sourceforge.net">countjoe@users.sourceforge.net</a>
040: * @version 0.8
041: */
042: public final class ChannelManager {
043: public static char allowUserChannels;
044: public String defaultChannel;
045: private int defaultCount;
046: private static Hashtable systemChannels;
047: private static Hashtable userChannels;
048: public static final String eName = "Invalid Channel Name";
049: public static final String eAllowed = "User Channels not allowed";
050: public static final String eAdmin = "Admin only operation";
051:
052: /**
053: * Constructor to setup variables
054: */
055: ChannelManager() {
056: allowUserChannels = 'y';
057: defaultChannel = "Lobby";
058: defaultCount = 0;
059: systemChannels = null;
060: userChannels = null;
061: }
062:
063: /**
064: * sets the default channel for the server
065: * @param name the name of the channel
066: * @return true on success, false otherwise (if its not a valid channeL)
067: */
068: public boolean setDefaultChannel(String name) {
069: if (!name.equals(defaultChannel) && !isValidChannel(name)) {
070: return false;
071: }
072: defaultChannel = name;
073: return true;
074: }
075:
076: /**
077: * creates a new system channel (if valid name)
078: * @param name the name of the channel
079: * @param pass the password for the channel, can be null if no
080: * password required
081: * @return true on success, false otherwise (if its not a valid channeL)
082: */
083: public boolean addSystemChannel(String name, String pass) {
084: if (!isValidChannel(name)) {
085: return false;
086: }
087: if (systemChannels == null) {
088: systemChannels = new Hashtable();
089: }
090: systemChannels.put(name, new ChannelManagerItem(pass));
091: return true;
092: }
093:
094: /**
095: * creates a new user channel (if valid name and is allowed)
096: * @param name the name of the channel
097: * @param pass the password for the channel, can be null if no
098: * password required
099: * @param cc the client requesting the channel
100: * @return null on success, reason otherwise (if its not a valid channeL)
101: */
102: public String addUserChannel(String name, String pass,
103: ClientConnection cc) {
104: if (allowUserChannels == 'n') {
105: return eAllowed;
106: }
107: if (allowUserChannels == 'a' && !cc.isAdmin()) {
108: return eAdmin;
109: }
110: if (!isValidChannel(name)) {
111: return eName;
112: }
113: if (userChannels == null) {
114: userChannels = new Hashtable();
115: }
116: userChannels.put(name, new ChannelManagerItem(pass));
117: return null;
118: }
119:
120: /**
121: * adds a user to the specified channel
122: * @param name the name of the channel
123: * @param pass the password to use for the channel, can be null
124: * @return true on success, false otherwise (if its not a valid channel,
125: * or invalied passphrase)
126: */
127: public boolean userAdd(String name, String pass) {
128: if (defaultChannel.equals(name)) {
129: defaultCount++;
130: return true;
131: }
132:
133: if (systemChannels != null && systemChannels.containsKey(name)) {
134: ChannelManagerItem value = (ChannelManagerItem) systemChannels
135: .get(name);
136: if (value == null) {
137: return false;
138: }
139: if (value.pass == null || value.pass.equals(pass)) {
140: value.countpp();
141: return true;
142: }
143: return false;
144: }
145: if (userChannels != null && userChannels.containsKey(name)) {
146: ChannelManagerItem value = (ChannelManagerItem) userChannels
147: .get(name);
148: if (value == null) {
149: return false;
150: }
151: if (value.pass == null || value.pass.equals(pass)) {
152: value.countpp();
153: return true;
154: }
155: }
156: return false;
157: }
158:
159: /**
160: * removes a user from the specified channel, only used on user channels
161: * @param name the name of the channel
162: * @return true when the operation emptied the channel and the channel
163: * was removed, false if failed or did not empty channel
164: */
165: public boolean userDel(String name) {
166: if (defaultChannel.equals(name)) {
167: defaultCount--;
168: return false;
169: }
170:
171: if (systemChannels != null && systemChannels.containsKey(name)) {
172: ChannelManagerItem value = (ChannelManagerItem) systemChannels
173: .get(name);
174: if (value != null) {
175: value.countmm();
176: }
177: return false;
178: }
179: if (userChannels != null && userChannels.containsKey(name)) {
180: ChannelManagerItem value = (ChannelManagerItem) userChannels
181: .get(name);
182: if (value == null) {
183: return false;
184: }
185: if (value.countmm()) {
186: userChannels.remove(name);
187: return true;
188: }
189: }
190: return false;
191: }
192:
193: /**
194: * checks to see if the channel can be created
195: * @param name the name of the channel
196: * @return true if valid channel
197: */
198: public boolean isValidChannel(String name) {
199: if (defaultChannel.equals(name)
200: || (systemChannels != null && systemChannels
201: .containsKey(name))
202: || (userChannels != null && userChannels
203: .containsKey(name)) || name.length() > 12
204: || !name.matches("[\\w_-]+?")) {
205: return false;
206: }
207: return true;
208: }
209:
210: /**
211: * checks to see if the channel exists
212: * @param name the name of the channel
213: * @return true if channel exists
214: */
215: public boolean channelExists(String name) {
216: if (defaultChannel.equals(name)
217: || (systemChannels != null && systemChannels
218: .containsKey(name))
219: || (userChannels != null && userChannels
220: .containsKey(name))) {
221: return true;
222: }
223: return false;
224: }
225:
226: /**
227: * checks to see if channel has password
228: * @return "" if name has pass, null otherwise
229: */
230: public String channelHasPass(String name) {
231: if (defaultChannel.equals(name)) {
232: return null;
233: } else if (systemChannels != null
234: && systemChannels.containsKey(name)) {
235: ChannelManagerItem value = (ChannelManagerItem) systemChannels
236: .get(name);
237: if (value != null) {
238: if (value.pass != null) {
239: return "";
240: }
241: }
242: return null;
243: } else if (userChannels != null
244: && userChannels.containsKey(name)) {
245: ChannelManagerItem value = (ChannelManagerItem) userChannels
246: .get(name);
247: if (value != null) {
248: if (value.pass != null) {
249: return "";
250: }
251: }
252: return null;
253: }
254: return null;
255: }
256:
257: /**
258: * returns an enumeration of all the contained channels
259: * @return an enumeration of all contained channels
260: */
261: public Enumeration enumerate() {
262: Vector all = new Vector();
263: all.add(defaultChannel);
264: if (systemChannels != null) {
265: Enumeration e = systemChannels.keys();
266: while (e.hasMoreElements()) {
267: all.add(e.nextElement());
268: }
269: }
270: if (userChannels != null) {
271: Enumeration e = userChannels.keys();
272: while (e.hasMoreElements()) {
273: all.add(e.nextElement());
274: }
275: }
276: return all.elements();
277: }
278:
279: /**
280: * storage class for placing in a HashTable
281: */
282: public class ChannelManagerItem {
283: /**
284: * number of users connected
285: */
286: public int count;
287:
288: /**
289: * password for channel, null for no password
290: */
291: public String pass;
292:
293: /**
294: * default constructor for default initialization
295: */
296: ChannelManagerItem() {
297: count = 0;
298: pass = null;
299: }
300:
301: /**
302: * creates a new channelmanageritem with p as its password
303: * @param p the password
304: */
305: ChannelManagerItem(String p) {
306: count = 0;
307: pass = (p == null ? null : new String(p));
308: }
309:
310: /**
311: * increment the user count
312: */
313: public void countpp() {
314: count++;
315: }
316:
317: /**
318: * decrement the user count
319: * @return true if decrement emptied room
320: */
321: public boolean countmm() {
322: count--;
323: if (count == 0)
324: return true;
325: return false;
326: }
327: }
328: }
|