mirror of
				https://github.com/simon987/Much-Assembly-Required.git
				synced 2025-10-30 16:06:52 +00:00 
			
		
		
		
	Merge a04207b5e0e90ad2ac2b592da7cabc8d0394d06a into 9bb0dc9034e1f00da330b56bb203c1a0dfbc03a0
This commit is contained in:
		
						commit
						66f25b3638
					
				| @ -6,6 +6,7 @@ import net.simon987.server.game.GameObject; | ||||
| import net.simon987.server.game.Programmable; | ||||
| import net.simon987.server.game.Updatable; | ||||
| import net.simon987.server.logging.LogManager; | ||||
| import net.simon987.server.crypto.CryptoProvider; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| @ -19,31 +20,42 @@ public class VaultDoor extends GameObject implements Programmable, Enterable, Up | ||||
|      */ | ||||
|     private char[] password; | ||||
| 
 | ||||
|     private RandomString random_string_generator; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether or not the vault door is opened | ||||
|      */ | ||||
|     private boolean opened; | ||||
|     private boolean open = false; | ||||
| 
 | ||||
|     private int openedTimer; | ||||
| 
 | ||||
|     /** | ||||
|      * Number of ticks to remain the door open | ||||
|      */ | ||||
|     private static final int OPEN_TIME = 4; //todo load from config | ||||
|     private int OPEN_TIME = GameServer.INSTANCE.getConfig().getInt("vault_door_open_time"); | ||||
| 
 | ||||
|     private int openedTimer = 0; | ||||
|     private int cypher_id; | ||||
| 
 | ||||
|     public VaultDoor(int cypher_id){ | ||||
|         this.cypher_id = cypher_id; | ||||
|         this.random_string_generator = new RandomStringGenerator(PASSWORD_LENGTH); | ||||
| 
 | ||||
|         password = GameServer.INSTANCE.getConfig().getRandomPassword(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void update() { | ||||
| 
 | ||||
|         if (openedTimer <= 0) { | ||||
| 
 | ||||
|             //Door was opened for OPEN_TIME, close it and regen password | ||||
|             password = getRandomPassword(); | ||||
|             opened = false; | ||||
| 
 | ||||
|             LogManager.LOGGER.fine("Closed Vault door ID: " + getObjectId()); | ||||
|         } else { | ||||
|             openedTimer--; | ||||
|         if (open){ | ||||
|             if (openedTimer <= 0) { | ||||
|                 //Door was open for OPEN_TIME, close it and regen password | ||||
|                 password = GameServer.INSTANCE.getConfig().getRandomPassword(); | ||||
|                 open = false; | ||||
|                 openedTimer = 0; | ||||
|                 LogManager.LOGGER.fine("Closed Vault door ID: " + getObjectId()); | ||||
|             } else { | ||||
|                 openedTimer--; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| @ -51,44 +63,42 @@ public class VaultDoor extends GameObject implements Programmable, Enterable, Up | ||||
|     @Override | ||||
|     public boolean sendMessage(char[] message) { | ||||
| 
 | ||||
|         System.out.println("VAULT: sendMessage" + new String(message));//todo rmv | ||||
| 
 | ||||
|         if (!opened) { | ||||
| 
 | ||||
|             if (Arrays.equals(message, password)) { | ||||
|                 opened = true; | ||||
|                 openedTimer = OPEN_TIME; | ||||
| 
 | ||||
|                 LogManager.LOGGER.fine("Opened Vault door ID: " + getObjectId()); | ||||
|         if (Arrays.equals(message, password)) { | ||||
|             if (!open) { | ||||
|                 openVault(); | ||||
|             } else { | ||||
|                 keepVaultOpen(); | ||||
|             } | ||||
| 
 | ||||
|             return true; | ||||
|         } else { | ||||
|             //Can't receive messages when opened | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void openVault(){ | ||||
|         open = true; | ||||
|         openedTimer = OPEN_TIME; | ||||
|         LogManager.LOGGER.fine("Opened Vault door ID: " + getObjectId()); | ||||
|     } | ||||
| 
 | ||||
|     private void keepVaultOpen(){ | ||||
|         open = true; | ||||
|         openedTimer = OPEN_TIME; | ||||
|     }   | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean enter(GameObject object) { | ||||
| 
 | ||||
|         LogManager.LOGGER.fine("VAULT enter " + opened); | ||||
| 
 | ||||
|         if (opened) { | ||||
|         LogManager.LOGGER.fine("VAULT enter " + open); | ||||
| 
 | ||||
|         if (open) { | ||||
|             //TODO: Enter in the vault | ||||
| 
 | ||||
| 
 | ||||
|             return true; | ||||
|         } else { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static char[] getRandomPassword() { | ||||
|         return "12345678".toCharArray();//todo actual random password | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public char getMapInfo() { | ||||
| @ -99,4 +109,5 @@ public class VaultDoor extends GameObject implements Programmable, Enterable, Up | ||||
|     public BasicDBObject mongoSerialise() { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -14,6 +14,7 @@ import net.simon987.server.logging.LogManager; | ||||
| import net.simon987.server.plugin.PluginManager; | ||||
| import net.simon987.server.user.User; | ||||
| import net.simon987.server.webserver.SocketServer; | ||||
| import net.simon987.server.crypto.CryptoProvider; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.net.UnknownHostException; | ||||
| @ -36,6 +37,8 @@ public class GameServer implements Runnable { | ||||
| 
 | ||||
|     private DayNightCycle dayNightCycle; | ||||
| 
 | ||||
|     private CryptoProvider cryptoProvider; | ||||
| 
 | ||||
|     public GameServer() { | ||||
| 
 | ||||
|         this.config = new ServerConfiguration("config.properties"); | ||||
| @ -45,6 +48,7 @@ public class GameServer implements Runnable { | ||||
| 
 | ||||
|         maxExecutionTime = config.getInt("user_timeout"); | ||||
| 
 | ||||
|         cryptoProvider = new CryptoProvider(); | ||||
| 
 | ||||
|         dayNightCycle = new DayNightCycle(); | ||||
| 
 | ||||
| @ -79,6 +83,10 @@ public class GameServer implements Runnable { | ||||
|         return eventDispatcher; | ||||
|     } | ||||
| 
 | ||||
|     public CryptoProvider getCryptoProvider(){ | ||||
|         return cryptoProvider; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void run() { | ||||
|         LogManager.LOGGER.info("(G) Started game loop"); | ||||
|  | ||||
| @ -0,0 +1,31 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| public class AutokeyCypher extends ShiftSubstitutionCypher { | ||||
| 
 | ||||
|     public AutokeyCypher(String charset){ | ||||
|         super(charset); | ||||
|     } | ||||
| 
 | ||||
|     public AutokeyCypher(){ | ||||
|         super(); | ||||
|     } | ||||
| 
 | ||||
|     @override | ||||
|     protected char encryptionShiftAt(int position, char[] plaintext, char[] key, char[] partial_cyphertext){ | ||||
|         if (i<key.length){ | ||||
|             return key[i]; | ||||
|         } else { | ||||
|             return plaintext[i-key.length]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @override | ||||
|     protected char decryptionShiftAt(int position, char[] cyphertext, char[] key, char[] partial_plaintext){ | ||||
|         if (i<key.length){ | ||||
|             return key[i]; | ||||
|         } else { | ||||
|             return partial_plaintext[i-key.length]; | ||||
|         } | ||||
|     } | ||||
| 	 | ||||
| } | ||||
| @ -0,0 +1,29 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| public class CaesarCypher extends ShiftSubstitutionCypher { | ||||
| 
 | ||||
| 	public CaesarCypher(String charset){ | ||||
| 		super(charset); | ||||
| 	} | ||||
| 
 | ||||
| 	public CaesarCypher(){ | ||||
|         super(); | ||||
| 	} | ||||
| 
 | ||||
|     /** | ||||
|      * Uses the first character of the key as the shift, and ignores the rest. | ||||
|      */ | ||||
|     @override | ||||
|     protected char encryptionShiftAt(int position, char[] plaintext, char[] key, char[] partial_cyphertext){ | ||||
|         return key[0]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Uses the first character of the key as the shift, and ignores the rest. | ||||
|      */ | ||||
|     @override | ||||
|     protected char decryptionShiftAt(int position, char[] cyphertext, char[] key, char[] partial_plaintext){ | ||||
|         return key[0]; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,22 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| 
 | ||||
| public class CryptoException extends Exception { | ||||
| 
 | ||||
|     public CryptoException () { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public CryptoException (String message) { | ||||
|         super (message); | ||||
|     } | ||||
| 
 | ||||
|     public CryptoException (Throwable cause) { | ||||
|         super (cause); | ||||
|     } | ||||
| 
 | ||||
|     public CryptoException (String message, Throwable cause) { | ||||
|         super (message, cause); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,43 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| public class CryptoProvider{ | ||||
| 
 | ||||
| 	public static final int NO_CYPHER = 0x0000; | ||||
| 	public static final int CAESAR_CYPHER = 0x0001; | ||||
| 	public static final int VIGENERE_CYPHER = 0x0002; | ||||
| 	public static final int AUTOKEY_CYPHER = 0x0003; | ||||
| 
 | ||||
|     public static final int PASSWORD_LENGTH = 8; // Same as CubotComPort.MESSAGE_LENGTH | ||||
| 
 | ||||
|     private charset; | ||||
| 	private password_generator; | ||||
| 
 | ||||
| 	public CryptoProvider(String charset){ | ||||
| 		this.charset = charset; | ||||
| 		this.password_generator = new RandomStringGenerator(PASSWORD_LENGTH,charset); | ||||
| 	} | ||||
| 
 | ||||
| 	public CryptoProvider(){ | ||||
| 		this(RandomStringGenerator.ALPHANUMERIC_CHARSET); | ||||
| 	} | ||||
| 
 | ||||
| 	public Cypher getCypher(int cypherId){ | ||||
| 		switch (cypherId){ | ||||
| 			case NO_CYPHER: | ||||
| 				return new NoCypher(charset); | ||||
| 			case CAESAR_CYPHER: | ||||
| 				return new CaesarCypher(charset); | ||||
| 			case VIGENERE_CYPHER: | ||||
| 				return new VigenereCypher(charset); | ||||
| 			case AUTOKEY_CYPHER: | ||||
| 				return new AutokeyCypher(charset); | ||||
| 			default: | ||||
| 				return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static String getRandomPassword(){ | ||||
| 		return this.password_generator.nextString().toCharArray(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										13
									
								
								Server/src/main/java/net/simon987/server/crypto/Cypher.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Server/src/main/java/net/simon987/server/crypto/Cypher.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| interface Cypher { | ||||
| 
 | ||||
| 	public char[] encrypt(char[] plaintext, char[] key); | ||||
| 
 | ||||
| 	public char[] decrypt(char[] cyphertext, char[] key); | ||||
| 
 | ||||
| 	public String textCharset(); | ||||
| 	 | ||||
| 	public String keyCharset(); | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,22 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| 
 | ||||
| public class InvalidCharsetException extends CryptoException { | ||||
| 
 | ||||
|     public InvalidCharsetException () { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public InvalidCharsetException (String message) { | ||||
|         super (message); | ||||
|     } | ||||
| 
 | ||||
|     public InvalidCharsetException (Throwable cause) { | ||||
|         super (cause); | ||||
|     } | ||||
| 
 | ||||
|     public InvalidCharsetException (String message, Throwable cause) { | ||||
|         super (message, cause); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,22 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| 
 | ||||
| public class InvalidKeyException extends CryptoException { | ||||
| 
 | ||||
|     public InvalidKeyException () { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public InvalidKeyException (String message) { | ||||
|         super (message); | ||||
|     } | ||||
| 
 | ||||
|     public InvalidKeyException (Throwable cause) { | ||||
|         super (cause); | ||||
|     } | ||||
| 
 | ||||
|     public InvalidKeyException (String message, Throwable cause) { | ||||
|         super (message, cause); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,50 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| public abstract class NoCypher implements Cypher { | ||||
| 
 | ||||
| 	private String charset; | ||||
| 
 | ||||
| 	public NoCypher(String charset){ | ||||
| 		this.charset = charset; | ||||
| 	} | ||||
| 
 | ||||
| 	public NoCypher(){ | ||||
| 		this(RandomStringGenerator.alphanum); | ||||
| 	} | ||||
| 
 | ||||
| 	public char[] encrypt(char[] plaintext, char[] key){ | ||||
|         char[] cyphertext = new char[plaintext.length]; | ||||
|         for (int i = 0; i< plaintext.length; i++){ | ||||
|         	char p = plaintext[i]; | ||||
|             int p_ind = charset.indexOf(p); | ||||
|             if (p_ind == -1){ | ||||
|                 throw InvalidCharsetException("Plaintext contains invalid character: "+p); | ||||
|             } | ||||
|             cyphertext[i] = p; | ||||
|         } | ||||
|         return cyphertext; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	public char[] decrypt(char[] cyphertext, char[] key){ | ||||
|         char[] plaintext = new char[cyphertext.length]; | ||||
|         for (int i = 0; i< cyphertext.length; i++){ | ||||
|         	char c = cyphertext[i]; | ||||
|             int c_ind = charset.indexOf(c); | ||||
|             if (c_ind == -1){ | ||||
|                 throw InvalidCharsetException("Cyphertext contains invalid character: "+c); | ||||
|             } | ||||
|             plaintext[i] = c; | ||||
|         } | ||||
|         return plaintext; | ||||
| 	} | ||||
| 
 | ||||
| 	public String textCharset(){ | ||||
| 		return charset; | ||||
| 	} | ||||
| 	 | ||||
| 	public String keyCharset(){ | ||||
| 		return charset; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,74 @@ | ||||
| /** | ||||
|  * | ||||
|  * Based on the RandomString class by erickson: | ||||
|  * https://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| import java.security.SecureRandom; | ||||
| import java.util.Locale; | ||||
| import java.util.Objects; | ||||
| import java.util.Random; | ||||
| 
 | ||||
| public class RandomStringGenerator { | ||||
| 
 | ||||
|     /** | ||||
|      * Generate a random string. | ||||
|      */ | ||||
|     public String nextString() { | ||||
|         for (int idx = 0; idx < buf.length; ++idx) | ||||
|             buf[idx] = charset[random.nextInt(charset.length)]; | ||||
|         return new String(buf); | ||||
|     } | ||||
| 
 | ||||
|     public static final String UPPER_ALPHA_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||||
|     public static final String LOWER_ALPHA_CHARSET = UPPER_ALPHA_CHARSET.toLowerCase(Locale.ROOT); | ||||
|     public static final String NUMERIC_CHARSET = "0123456789"; | ||||
|     public static final String ALPHANUMERIC_CHARSET = UPPER_ALPHA_CHARSET + LOWER_ALPHA_CHARSET + NUMERIC_CHARSET; | ||||
| 
 | ||||
|     private final Random random; | ||||
| 
 | ||||
|     private final char[] charset; | ||||
| 
 | ||||
|     private final char[] buf; | ||||
| 
 | ||||
|     public RandomStringGenerator(int length, Random random, String charset) { | ||||
|         if (length < 1) throw new IllegalArgumentException(); | ||||
|         if (charset.length() < 2) throw new IllegalArgumentException(); | ||||
|         this.random = Objects.requireNonNull(random); | ||||
|         this.charset = charset.toCharArray(); | ||||
|         this.buf = new char[length]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create an alphanumeric string generator. | ||||
|      */ | ||||
|     public RandomStringGenerator(int length, Random random) { | ||||
|         this(length, random, alphanum); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create an alphanumeric string generator using the given charset. | ||||
|      */ | ||||
|     public RandomStringGenerator(int length, String charset) { | ||||
|         this(length, new SecureRandom(), ALPHANUMERIC_CHARSET); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Create an alphanumeric strings from a secure generator. | ||||
|      */ | ||||
|     public RandomStringGenerator(int length) { | ||||
|         this(length, new SecureRandom(),ALPHANUMERIC_CHARSET); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create 8-character alphanumeric strings from a secure generator. | ||||
|      */ | ||||
|     public RandomStringGenerator() { | ||||
|         this(8); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,73 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| public abstract class ShiftSubstitutionCypher implements Cypher { | ||||
| 
 | ||||
| 	private String charset; | ||||
| 
 | ||||
| 	public ShiftSubstitutionCypher(String charset){ | ||||
| 		this.charset = charset; | ||||
| 	} | ||||
| 
 | ||||
| 	public ShiftSubstitutionCypher(){ | ||||
| 		this(RandomStringGenerator.alphanum); | ||||
| 	} | ||||
| 
 | ||||
|     protected abstract char encryptionShiftAt(int position, char[] plaintext, char[] key, char[] partial_cyphertext); | ||||
|     protected abstract char decryptionShiftAt(int position, char[] cyphertext, char[] key, char[] partial_plaintext); | ||||
| 
 | ||||
| 	public char[] encrypt(char[] plaintext, char[] key){ | ||||
|         if (key.length==0){ | ||||
|             throw InvalidKeyException("Key is empty"); | ||||
|         } | ||||
|         int charset_length = charset.length(); | ||||
|         char[] cyphertext = new char[plaintext.length]; | ||||
|         for (int i = 0; i< plaintext.length; i++){ | ||||
|             char p = plaintext[i]; | ||||
|             char k = encryptionShiftAt(i,plaintext,key,cyphertext); | ||||
|             int p_ind = charset.indexOf(p); | ||||
|             if (p_ind == -1){ | ||||
|                 throw InvalidCharsetException("Plaintext contains invalid character: "+p); | ||||
|             } | ||||
|             int k_ind = charset.indexOf(k); | ||||
|             if (k_ind == -1){ | ||||
|                 throw InvalidCharsetException("Key contains invalid character: "+k);  | ||||
|             } | ||||
|             int c_int = (p_ind+k_ind)%charset_length; | ||||
|             char c = charset.charAt(c_int); | ||||
|             cyphertext[i] = c; | ||||
|         } | ||||
|         return cyphertext; | ||||
| 	} | ||||
| 
 | ||||
| 	public char[] decrypt(char[] cyphertext, char[] key){ | ||||
|         if (key.length==0){ | ||||
|             throw InvalidKeyException("Key is empty"); | ||||
|         } | ||||
|         int charset_length = charset.length(); | ||||
|         char[] plaintext = new char[cyphertext.length]; | ||||
|         for (int i = 0; i< cyphertext.length; i++){ | ||||
|             char c = cyphertext[i]; | ||||
|             char k = decryptionShiftAt(i,cyphertext,key,plaintext); | ||||
|             int c_ind = charset.indexOf(c); | ||||
|             if (c_ind == -1){ | ||||
|                 throw InvalidCharsetException("Cyphertext contains invalid character: "+c); | ||||
|             } | ||||
|             int k_ind = charset.indexOf(k); | ||||
|             if (k_ind == -1){ | ||||
|                 throw InvalidCharsetException("Password contains invalid character: "+k);  | ||||
|             } | ||||
|             int p_int = (c_ind-k_ind)%charset_length; | ||||
|             char p = charset.charAt(p_int); | ||||
|             plaintext[i] = p; | ||||
|         } | ||||
|         return plaintext; | ||||
| 	} | ||||
| 
 | ||||
| 	public String textCharset(){ | ||||
| 		return charset; | ||||
| 	} | ||||
| 	 | ||||
| 	public String keyCharset(){ | ||||
| 		return charset; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| package net.simon987.server.crypto; | ||||
| 
 | ||||
| public class VigenereCypher extends ShiftSubstitutionCypher { | ||||
| 
 | ||||
| 	public VigenereCypher(String charset){ | ||||
| 		super(charset); | ||||
| 	} | ||||
| 
 | ||||
| 	public VigenereCypher(){ | ||||
| 		super(); | ||||
| 	} | ||||
| 
 | ||||
|     @override | ||||
|     protected char encryptionShiftAt(int position, char[] plaintext, char[] key, char[] partial_cyphertext){ | ||||
|         int j = i % key.length; | ||||
|         return key[j]; | ||||
|     } | ||||
| 
 | ||||
|     @override | ||||
|     protected char decryptionShiftAt(int position, char[] cyphertext, char[] key, char[] partial_plaintext){ | ||||
|         int j = i % key.length; | ||||
|         return key[j]; | ||||
|     } | ||||
|      | ||||
| } | ||||
| @ -84,3 +84,7 @@ wg_maxCopperCount=2 | ||||
| # ---------------------------------------------- | ||||
| # Maximum execution time of user code in ms | ||||
| user_timeout=100 | ||||
| 
 | ||||
| 
 | ||||
| # ---------------------------------------------- | ||||
| vault_door_open_time=4 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user