/* ** j###t ########## #### #### ** j###t ########## #### #### ** j###T "###L J###" ** ######P' ########## ######### ** ######k, ########## T######T ** ####~###L #### ** #### q###L ########## .##### ** #### \###L ########## #####" ** ** $Id$ ** ** Class History ** ** Date Name Description ** ---------|------------|----------------------------------------------- ** 19Aug98 subtle start of recorded history ** */ package key; import key.primitive.*; import java.util.Enumeration; import java.io.*; import java.util.StringTokenizer; /** * It's too hard to give sites a unique name, but its useful to * store them in a container to save us writing custom load/save * routines. It also means if you *do* know a sites 'number' on * the program, you have a chance ;) */ public class Site extends Atom implements Subnet { private static final long serialVersionUID = 7084061282031417477L; public static final AtomicElement[] ELEMENTS = { AtomicElement.construct( Site.class, Paragraph.class, "notes", AtomicElement.PUBLIC_FIELD, "some comments about this site" ), AtomicElement.construct( Site.class, String.class, "banType", AtomicElement.PUBLIC_FIELD, "the type of the ban on this site: N, C, or O" ), AtomicElement.construct( Site.class, Player.class, "bannedBy", AtomicElement.PUBLIC_FIELD, "the player who banned this site" ), AtomicElement.construct( Site.class, DateTime.class, "bannedAt", AtomicElement.PUBLIC_FIELD, "when this site was banned" ), AtomicElement.construct( Site.class, DateTime.class, "bannedUntil", AtomicElement.PUBLIC_FIELD, "when this site will be un-banned" ), AtomicElement.construct( Site.class, TimeStatistics.class, "connectionStats", AtomicElement.PUBLIC_FIELD, "information about who connects from this site" ), AtomicElement.construct( Site.class, String.class, "alpha", AtomicElement.PUBLIC_FIELD | AtomicElement.READ_ONLY, "the domain name of this site" ), AtomicElement.construct( Site.class, String.class, "reasonBanned", AtomicElement.PUBLIC_FIELD, "the reason this site was banned" ) }; public static final AtomicStructure STRUCTURE = new AtomicStructure( Atom.STRUCTURE, ELEMENTS ); public Paragraph notes = new TextParagraph( TextParagraph.CENTERALIGNED, "" ); /** * The type of ban that is on the site: * N for newbie * C for siteban * 0 length string for no ban at all */ public String banType = "O"; public Reference bannedBy = Reference.EMPTY; public DateTime bannedAt = null; public DateTime bannedUntil = null; public final TimeStatistics connectionStats = (TimeStatistics) Factory.makeAtom( TimeStatistics.class, "connectionStats" ); public String reasonBanned = ""; /** * The IP mask. This is basically * the array that was returned by InetAddress */ public int[] mask; /** * The alpha for this site. For instance, * UTS is uts.edu.au (thats the whole site * name). (Can be null if no DNS entry) */ public String alpha; private final String SITE_LOG = "site"; public Site() { } public AtomicStructure getDeclaredStructure() { return( STRUCTURE ); } public final boolean newbiesAllowed() { checkBans(); return( !banType.equals( "N" ) ); } public final boolean connectionsAllowed() { checkBans(); return( !banType.equals( "C" ) ); } public final TimeStatistics connectionStats() { return( connectionStats ); } /* public final TimeStatistics connectionStatistics() { return( connectionStats ); } */ /** * The passed in string MUST be lowercase */ protected void resetTrailer( String newT ) { if( alpha != null && !alpha.equals( newT ) ) ((Network)getParent()).unRegisterTrailer( alpha ); alpha = newT; ((Network)getParent()).registerTrailer( this ); } /** * You can construct a Site with any IP, but * only the relevant IP's will be stored. */ public Site( int[] ip ) { setMask( ip ); } public void setMask( int[] ip ) { if( ip[0] < 128 ) mask = new int[1]; else if( ip[0] < 192 ) mask = new int[2]; else if( ip[0] < 224 ) mask = new int[3]; else mask = new int[4]; for( int i = 0; i < mask.length; i++ ) mask[i] = ip[i]; alpha = null; setKey( new Integer( mask[ mask.length - 1 ] ) ); } public int[] getMask() { return( mask ); } public String getTrailer() { return( alpha ); } /** * Some sites will have dns entries for certain IP's * within them, and not have entries for others. We * also need this code to find the 'lowest common * denominator' in the site alpha. */ public void registerSite( String dns ) { if( dns != null ) { if( alpha == null ) resetTrailer( dns.toLowerCase() ); else { dns = dns.toLowerCase(); String newTrailer = alpha; while( !dns.endsWith( newTrailer ) ) { // okay, we need to find the common parts of these // two strings, from the end. For instance, the // alpha might currently be 'progsoc.uts.edu.au', // as we've only had connections from 138.25. from // within progsoc. However, when we get a connection // from say, socs: 'charlie.socs.uts.edu.au', then // the tailer is known to be inaccurate. int tIndex = newTrailer.indexOf( '.' ); if( tIndex == -1 ) { Log.log( SITE_LOG, "ran out of trail sections trying to find a common DNS section" ); return; } try { newTrailer = newTrailer.substring( tIndex+1 ); } catch( StringIndexOutOfBoundsException e ) { Log.log( SITE_LOG, "got a trailing period in a alpha '" + alpha + "'. aborting registerSite()" ); return; } } resetTrailer( newTrailer ); } } //Log.log( SITE_LOG, "DNS entry '" + dns + "' registered inside " + toString() ); } public String toString() { StringBuffer sb = new StringBuffer(); for( int i = 0; i < mask.length; i++ ) { sb.append( mask[i] ); sb.append( "." ); } if( alpha != null ) return( alpha + " [" + sb.toString() + "]" ); else return( sb.toString() ); } private void checkBans() { DateTime now = new DateTime(); if( bannedUntil == null ) return; long diff = now.getTime() - bannedUntil.getTime(); if( diff >= 0 ) { //Ban has expired banType = ""; bannedBy = null; bannedAt = now; bannedUntil = null; reasonBanned = "Site ban expired"; } } public final void setBan( String banType, Player p, DateTime now, DateTime until, String reason ) { permissionList.check( modifyAction ); banType = banType; bannedBy = p.getThis(); bannedAt = now; bannedUntil = until; reasonBanned = reason; } }