View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.plugin.opennap.user;
21  
22  import javax.swing.Action;
23  
24  import org.xnap.peer.AbstractPeer;
25  import org.xnap.plugin.opennap.OpenNapPlugin;
26  import org.xnap.plugin.opennap.action.OpenNapAddToHotlistAction;
27  import org.xnap.plugin.opennap.action.OpenNapBrowseAction;
28  import org.xnap.plugin.opennap.action.OpenNapChatAction;
29  import org.xnap.plugin.opennap.action.OpenNapWhoisAction;
30  import org.xnap.plugin.opennap.net.OpenNapServer;
31  import org.xnap.plugin.opennap.net.msg.MessageHandler;
32  import org.xnap.plugin.opennap.net.msg.client.PrivateMessage;
33  import org.xnap.plugin.opennap.net.msg.client.WhoisRequestMessage;
34  import org.xnap.util.Preferences;
35  
36  public class OpenNapUser extends AbstractPeer {
37  
38      //--- Constant(s) ---
39  
40      public static final int WHOIS_REQUERY_INTERVALL = 2 * 60 * 1000;
41      public static final int WHOIS_RESENT_INTERVALL = 10 * 60 * 1000;
42  
43      //--- Data field(s) ---
44  
45      private int connectDuration;
46      private boolean fakeLocalFileCount;
47      private int downloadCount = 0;
48      private String host;
49      private long lastSeen;
50  
51      /***
52       * Milli seconds when last whois query for this user was sent.
53       */
54      private long lastWhoisSent = 0;
55  
56      /***
57       * Milli seconds when last whois query for this user was received.
58       */
59      private long lastWhoisResponse = 0;
60  
61      private String level;
62  
63      /***
64       * The global instance of this user.
65       */
66      private OpenNapGlobalUser parent;
67  
68      private int port;
69      private OpenNapServer server;
70      private String status;
71      private int uploadCount = 0;
72  
73      //--- Constructor(s) ---
74  
75      public OpenNapUser(String name, OpenNapServer server)
76      {
77  		super(name);
78  
79  		this.server = server;
80  
81  		fakeLocalFileCount = name.equals(server.getNick());
82      }
83  
84      //--- Method(s) ---
85  
86  	/***
87  	 * Returns true, if this user's client support direct browse.
88  	 */
89  	public boolean canDirectBrowse()
90  	{
91  		String client = getClientInfo();
92  		if (client != null) {
93  			client.toLowerCase();
94  			return (client.startsWith("xnap")
95  					|| client.startsWith("lopster")
96  					|| client.startsWith("2get")
97  					|| client.startsWith("utatane")
98  					|| client.startsWith("napchan")
99  					|| client.startsWith("nap"));
100 		}
101 		return false;
102 	}
103 
104 
105 	/***
106 	 * Returns true, if the name of <code>o</code> equals the name of the user.
107 	 */
108     public boolean equals(Object o) 
109     {
110 	    if (o instanceof OpenNapUser) {
111 			OpenNapUser user = (OpenNapUser)o;
112 			return getName().equals(user.getName());
113 	    }
114 		return false;
115 	}
116 
117     public Action[] getActions()
118     {
119 		return new Action[] { 
120 			new OpenNapBrowseAction(this),
121 			new OpenNapChatAction(this), 
122 			new OpenNapWhoisAction(this), 
123 			new OpenNapAddToHotlistAction(this),
124 		};
125     }
126 
127     public int getConnectDuration()
128     {
129 		return connectDuration;
130     }
131 
132 	/***
133 	 * Returns the download count as received by a whois response.
134 	 */
135     public int getDownloadCount()
136     {
137 		return downloadCount;
138     }
139 
140     public String getHost()
141     {
142 		return host;
143     }
144 
145     public long getLastSeen()
146     {
147 		return lastSeen;
148     }
149 
150     public String getLevel()
151     {
152 		return level;
153     }
154 
155     public int getLocalDownloadCount()
156     {
157 		return getParent().getDownloadCount();
158     }
159     
160     public int getLocalUploadCount()
161     {
162 		return getParent().getUploadCount();
163     }
164 
165     public OpenNapGlobalUser getParent()
166     {
167 		if (parent == null) {
168 			synchronized (this) {
169 				if (parent == null) {
170 					parent = OpenNapPlugin.getUserManager().get(getName());
171 				}
172 			}
173 		}
174 
175 		return parent;
176     }	
177 
178 	public int getPort()
179 	{
180 		return port;
181 	}
182 
183     public OpenNapServer getServer()
184     {
185 		return server;
186     }
187 
188     public String getStatus()
189     {
190 		return status;
191     }
192 
193 	public int getUploadCount()
194 	{
195 		return uploadCount;
196 	}
197 
198 	/***
199 	 * @return true, if download requests are permanently denied
200 	 */
201 	public boolean isDownloadDenied()
202 	{
203  	  	if (getParent().getMaxDownloads() == 0) {
204  	  	    return true;
205  	  	}
206 
207 		return false;
208 	}
209 
210 	/***
211 	 * @return true, if download requests are temporarily denied
212 	 */
213 	public boolean isDownloadLimitReached()
214 	{
215 		int maxDownloads = getParent().getMaxDownloads();
216 		if (maxDownloads == OpenNapGlobalUser.TRANSFER_DEFAULT) {
217 			Preferences prefs = Preferences.getInstance();
218 			return prefs.getLimitDownloadsPerUser()
219 				? getLocalDownloadCount() >= prefs.getMaxDownloadsPerUser()
220 				: false;
221 		}
222 		else {
223 			return getLocalDownloadCount() >= parent.getMaxDownloads();
224 		}
225 	}
226 
227 	/***
228 	 * Checks if peer shares enough to be allowed to download from
229 	 * us. Serves to block leechers. Automatically calls
230 	 * {@link #update()} if needed.
231 	 *
232 	 * @return true, if uploads are permanently denied
233 	 */
234 	public boolean isUploadDenied()
235 	{
236  	  	if (getParent().getMaxUploads() == 0) {
237  	  	    return true;
238  	  	}
239 
240 		Preferences prefs = Preferences.getInstance();
241 		if (prefs.getUseMinimumShares()) {
242 	  	    if (update() && getFileCount() < prefs.getMinimumShares()) {
243 				// send message to peer
244 				if (prefs.getSendMinimumSharesMessage()
245 					&& !getParent().isMinimumSharesMessageSent()) {
246 
247 					getParent().setMinimumSharesMessageSent(true);
248 					PrivateMessage msg = new PrivateMessage
249 						(getName(), prefs.getMinimumSharesMessage());
250 					MessageHandler.send(server, msg);					
251 				}
252 				return true;
253 	  	    }
254 	  	}
255 
256 	  	return false;
257 	} 
258 			
259 	/***
260 	 * @return true, if uploads are temporarily denied
261 	 */
262 	public boolean isUploadLimitReached()
263 	{
264 		int maxUploads = getParent().getMaxUploads();
265 		if (maxUploads == OpenNapGlobalUser.TRANSFER_DEFAULT) {
266 			Preferences prefs = Preferences.getInstance();
267 			return prefs.getLimitDownloadsPerUser()
268 				? getLocalUploadCount() >= prefs.getMaxUploadsPerUser()
269 				: false;
270 		}
271 		else {
272 			return getLocalUploadCount() >= parent.getMaxUploads();
273 		}
274 	}
275 
276     public boolean isUpToDate()
277     {
278 		return (System.currentTimeMillis() - lastWhoisResponse
279 				< WHOIS_RESENT_INTERVALL);
280     }
281 
282     /***
283      * Called by message class when whois query was received.
284      */
285     public void notifyWhoisReceived()
286     {
287 		lastWhoisResponse = System.currentTimeMillis();
288 		lastWhoisSent = 0;
289     }
290 
291     public void setConnectDuration(int newValue)
292     {
293 		connectDuration = newValue;
294     }
295 
296 	public void setDownloadCount(int newValue)
297 	{
298 		downloadCount = newValue;
299 	}
300 
301     public void setHost(String newValue)
302     {
303 		this.host = newValue;
304     }
305 
306     public void setLastSeen(long newValue)
307     {
308 		lastSeen = newValue;
309     }
310 
311     public void setLevel(String newValue)
312     {
313 		level = newValue;
314     }
315 
316 	public void setPort(int newValue)
317 	{
318 		port = newValue;
319 	}
320 
321 	/***
322 	 * Maps OpenNap types to real values.
323 	 */
324 	public void setLinkSpeed(int newValue)
325 	{
326 		switch (newValue) {
327 		case 0:
328 			super.setLinkSpeed(0);
329 			break;
330 		case 1:
331 			super.setLinkSpeed(14);
332 			break;
333 		case 2:
334 			super.setLinkSpeed(28);
335 			break;
336 		case 3:
337 			super.setLinkSpeed(33);
338 			break;
339 		case 4:
340 			super.setLinkSpeed(56);
341 			break;
342 		case 5:
343 			super.setLinkSpeed(64);
344 			break;
345 		case 7:
346 			super.setLinkSpeed(500);
347 			break;
348 		case 8:
349 			super.setLinkSpeed(768);
350 			break;
351 		case 9:
352 			super.setLinkSpeed(3000);
353 			break;
354 		case 10:
355 			super.setLinkSpeed(5000);
356 			break;
357 		default:
358 			super.setLinkSpeed(0);
359 		}
360 	}
361 
362     public void setStatus(String newValue)
363     {
364 		status = newValue;
365     }
366 
367 	public void setUploadCount(int newValue)
368 	{
369 		uploadCount = newValue;
370 	}
371 
372     public boolean shouldRequery()
373     {
374 		return (System.currentTimeMillis() - lastWhoisSent
375 				> WHOIS_REQUERY_INTERVALL);
376     }
377 
378     public String toString() 
379     {
380 		StringBuffer sb = new StringBuffer();
381 		sb.append(getName());
382 		if (server != null) {
383 			sb.append("@");
384 			sb.append(server.getHost());
385 		}
386 
387 		return sb.toString();
388     }
389 
390     /***
391      * Sends a whois query to the server if not up to date.
392      *
393      * @return true, if up to date; false, if not.
394      */
395     public boolean update(boolean force)
396     {
397 		if (force || !isUpToDate()) {
398 			if (shouldRequery()) {
399 				MessageHandler.send(server, 
400 									new WhoisRequestMessage(getName()));
401 				lastWhoisSent = System.currentTimeMillis();
402 			}
403 			return false;
404 		}
405 	    
406 		return true;
407     }
408 
409     public boolean update()
410     {
411 		return update(false);
412     }
413 
414 	//--- Inner Class(es) ---
415 
416 }