package dangerzone;
/*
 * This code is copyright Richard H. Clark, TheyCallMeDanger, OreSpawn, 2015-2020.
 * You may use this code for reference for modding the DangerZone game program,
 * and are perfectly welcome to cut'n'paste portions for your mod as well.
 * DO NOT USE THIS CODE FOR ANY PURPOSE OTHER THAN MODDING FOR THE DANGERZONE GAME.
 * DO NOT REDISTRIBUTE THIS CODE. 
 * 
 * This copyright remains in effect until January 1st, 2021. 
 * At that time, this code becomes public domain.
 * 
 * WARNING: There are bugs. Big bugs. Little bugs. Every size in-between bugs.
 * This code is NOT suitable for use in anything other than this particular game. 
 * NO GUARANTEES of any sort are given, either express or implied, and Richard H. Clark, 
 * TheyCallMeDanger, OreSpawn are not responsible for any damages, direct, indirect, or otherwise. 
 * You should have made backups. It's your own fault for not making them.
 * 
 * NO ATTEMPT AT SECURITY IS MADE. This code is USE AT YOUR OWN RISK.
 * Regardless of what you may think, the reality is, that the moment you 
 * connected your computer to the Internet, Uncle Sam, among many others, hacked it.
 * DO NOT KEEP VALUABLE INFORMATION ON INTERNET-CONNECTED COMPUTERS.
 * Or your phone...
 * 
 */

import java.util.StringTokenizer;

import dangerzone.blocks.Blocks;
import dangerzone.entities.Entity;
import dangerzone.entities.EntityCloud;
import dangerzone.entities.EntityFire;
import dangerzone.entities.EntityLiving;
import dangerzone.entities.Temperament;



public class DZCommandHandler extends CommandHandler {
	
	public boolean doCommand(Player pl, String cmd){
		String s;
		StringTokenizer st = new StringTokenizer(cmd);
		boolean retval = false;

		if(!pl.world.isServer)return false;

		//TODO FIXME - some day we should record commands to a log file...
		
		//strip off playername
		s = st.nextToken();
		if(st.hasMoreTokens()){
			s = st.nextToken();
		}else{
			return true; //error in command. pretend we handled it!
		}
		
		if(s.equalsIgnoreCase("time")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.TIME) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				if(s.equalsIgnoreCase("set")){
					if(st.hasMoreTokens()){
						s = st.nextToken();
						if(s.equalsIgnoreCase("day")){
							DangerZone.server_world.timetimer = DangerZone.server_world.lengthOfDay/4; //noon!
							DangerZone.server.sendTimeToAll(DangerZone.server_world.timetimer, DangerZone.server_world.lengthOfDay);
							retval = true;

						}else if(s.equalsIgnoreCase("night")){
							DangerZone.server_world.timetimer = DangerZone.server_world.lengthOfDay*3/4; //midnight!
							DangerZone.server.sendTimeToAll(DangerZone.server_world.timetimer, DangerZone.server_world.lengthOfDay);
							retval = true;

						}else if(s.equalsIgnoreCase("dawn")){
							DangerZone.server_world.timetimer = 0; 									//morning
							DangerZone.server.sendTimeToAll(DangerZone.server_world.timetimer, DangerZone.server_world.lengthOfDay);
							retval = true;

						}else if(s.equalsIgnoreCase("dusk")){
							DangerZone.server_world.timetimer = DangerZone.server_world.lengthOfDay/2; //evening!
							DangerZone.server.sendTimeToAll(DangerZone.server_world.timetimer, DangerZone.server_world.lengthOfDay);
							retval = true;

						}else{
							int newtime;
							try{
								newtime = Integer.parseInt(s);
							}catch(NumberFormatException e){
								newtime = 0;
							}
							if(newtime >= 0 && newtime <= DangerZone.server_world.lengthOfDay){
								DangerZone.server_world.timetimer = newtime;
								DangerZone.server.sendTimeToAll(DangerZone.server_world.timetimer, DangerZone.server_world.lengthOfDay);
								retval = true;

							}
						}
					}
				}
			}
		}else if(s.equalsIgnoreCase("tp") || s.equalsIgnoreCase("teleport") ){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.TELEPORT) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				Entity e = DangerZone.server.entityManager.findPlayerByName(s);
				if(e != null){

					Utils.doTeleport(pl, e.dimension, e.posx, e.posy, e.posz);		
					retval = true;

				}else{
					int newx, newy, newz;
					newx=newy=newz=0;
					try{
						newx = Integer.parseInt(s);
					}catch(NumberFormatException ex){
						newx = 0;
					}
					if(st.hasMoreTokens()){
						s = st.nextToken();
						try{
							newy = Integer.parseInt(s);
						}catch(NumberFormatException ex){
							newy = 0;
						}
					}
					if(st.hasMoreTokens()){
						s = st.nextToken();
						try{
							newz = Integer.parseInt(s);
						}catch(NumberFormatException ex){
							newz = 0;
						}
					}
					if(newx > 0 && newy > 0 && newy < 256 && newz > 0){
						//close enough. go!

						Utils.doTeleport(pl, pl.dimension, (double)newx, (double)newy, (double)newz);		
						retval = true;

					}
				}
			}
		}else if(s.equalsIgnoreCase("stop") || s.equalsIgnoreCase("shutdown") ){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.SHUTDOWN) == 0)return false;
			DangerZone.gameover = 1;
			retval = true;

		}else if(s.equalsIgnoreCase("show")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.MISC) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				if(s.equalsIgnoreCase("eid")){
					int i;
					for(i=1;i<DangerZone.max_entities;i++){
						Entity e = DangerZone.server.entityManager.findEntityByID(i);
						if(e != null){
							e.setPetName(String.format("%d", i));
							retval = true;
						}
					}

				}else{
					int i;
					for(i=1;i<DangerZone.max_entities;i++){
						Entity e = DangerZone.server.entityManager.findEntityByID(i);
						if(e != null){
							e.setPetName(null);
							retval = true;
						}
					}

				}
			}
		}else if(s.equalsIgnoreCase("weather")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.WEATHER) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				if(s.equalsIgnoreCase("clear")){
					int i;
					for(i=1;i<DangerZone.max_entities;i++){
						Entity e = DangerZone.server.entityManager.findEntityByID(i);
						if(e != null){
							if(e instanceof EntityCloud){
								if(e.getBID() == Blocks.cloud_thunder.blockID || e.getBID() == Blocks.cloud_rain.blockID){
									e.deadflag = true;
								}
							}
							retval = true;
						}
					}

				}
			}				
		}else if(s.equalsIgnoreCase("kill")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.KILL) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				if(s.equalsIgnoreCase("all")){
					int i;
					for(i=1;i<DangerZone.max_entities;i++){
						Entity e = DangerZone.server.entityManager.findEntityByID(i);
						if(e != null){
							if(!(e instanceof Player) && e instanceof EntityLiving){
								e.deadflag = true;
							}

						}
					}
					retval = true;

				}
				if(s.equalsIgnoreCase("hostile")){
					int i;
					for(i=1;i<DangerZone.max_entities;i++){
						Entity e = DangerZone.server.entityManager.findEntityByID(i);
						if(e != null){
							if(e.temperament == Temperament.HOSTILE){
								e.deadflag = true;
							}								
						}
					}
					retval = true;

				}
			}
			
		}else if(s.equalsIgnoreCase("nofire")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.NOFIRE) == 0)return false;			
			int i;
			for(i=1;i<DangerZone.max_entities;i++){
				Entity e = DangerZone.server.entityManager.findEntityByID(i);
				if(e != null){
					if(!(e instanceof Player) && e instanceof EntityFire){
						e.deadflag = true;
					}

				}
			}
			retval = true;

		}else if(s.equalsIgnoreCase("op")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				Entity e = DangerZone.server.entityManager.findPlayerByName(s);
				if(e != null){
					Player plyr = (Player)e;
					plyr.player_privs = 0xffffffff;
					DangerZone.server.save_privs(plyr.myname, plyr.player_privs);
					retval = true;
				}
			}
		}else if(s.equalsIgnoreCase("deop")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				Entity e = DangerZone.server.entityManager.findPlayerByName(s);
				if(e != null){
					Player plyr = (Player)e;
					plyr.player_privs = 0x0;
					DangerZone.server.save_privs(plyr.myname, plyr.player_privs);
					retval = true;
				}
			}
		}else if(s.equalsIgnoreCase("givepriv")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				Entity e = DangerZone.server.entityManager.findPlayerByName(s);
				if(e != null){
					
					int newpriv = 0;
					if(st.hasMoreTokens()){
						s = st.nextToken();
						if(s.equalsIgnoreCase("gamemode"))newpriv = PlayerPrivs.GAMEMODE;
						if(s.equalsIgnoreCase("op"))newpriv = PlayerPrivs.OPERATOR;
						if(s.equalsIgnoreCase("teleport"))newpriv = PlayerPrivs.TELEPORT;
						if(s.equalsIgnoreCase("kill"))newpriv = PlayerPrivs.KILL;
						if(s.equalsIgnoreCase("weather"))newpriv = PlayerPrivs.WEATHER;
						if(s.equalsIgnoreCase("misc"))newpriv = PlayerPrivs.MISC;
						if(s.equalsIgnoreCase("time"))newpriv = PlayerPrivs.TIME;
						if(s.equalsIgnoreCase("shutdown"))newpriv = PlayerPrivs.SHUTDOWN;
						if(s.equalsIgnoreCase("nofire"))newpriv = PlayerPrivs.NOFIRE;
					}
										
					Player plyr = (Player)e;
					plyr.player_privs |= newpriv;
					DangerZone.server.save_privs(plyr.myname, plyr.player_privs);
					retval = true;
				}
			}
		}else if(s.equalsIgnoreCase("takepriv")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				Entity e = DangerZone.server.entityManager.findPlayerByName(s);
				if(e != null){
					
					int newpriv = 0;
					if(st.hasMoreTokens()){
						s = st.nextToken();
						if(s.equalsIgnoreCase("gamemode"))newpriv = PlayerPrivs.GAMEMODE;
						if(s.equalsIgnoreCase("op"))newpriv = PlayerPrivs.OPERATOR;
						if(s.equalsIgnoreCase("teleport"))newpriv = PlayerPrivs.TELEPORT;
						if(s.equalsIgnoreCase("kill"))newpriv = PlayerPrivs.KILL;
						if(s.equalsIgnoreCase("weather"))newpriv = PlayerPrivs.WEATHER;
						if(s.equalsIgnoreCase("misc"))newpriv = PlayerPrivs.MISC;
						if(s.equalsIgnoreCase("time"))newpriv = PlayerPrivs.TIME;
						if(s.equalsIgnoreCase("shutdown"))newpriv = PlayerPrivs.SHUTDOWN;
						if(s.equalsIgnoreCase("nofire"))newpriv = PlayerPrivs.NOFIRE;
					}
										
					Player plyr = (Player)e;
					plyr.player_privs &= ~newpriv;
					DangerZone.server.save_privs(plyr.myname, plyr.player_privs);
					retval = true;
				}
			}
		}else if(s.equalsIgnoreCase("mount")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0 && (pl.player_privs & PlayerPrivs.MISC) == 0)return false;
			int rider=0, ridden=0;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				try{
					rider = Integer.parseInt(s);
				}catch(NumberFormatException ex){
					rider = 0;
				}
			}
			if(st.hasMoreTokens()){
				s = st.nextToken();
				try{
					ridden = Integer.parseInt(s);
				}catch(NumberFormatException ex){
					ridden = 0;
				}
			}
			if(rider != 0 && ridden != 0){
				Entity top, bottom;
				top =  DangerZone.server.entityManager.findEntityByID(rider);
				if(top != null){
					bottom =  DangerZone.server.entityManager.findEntityByID(ridden);
					if(bottom != null){
						bottom.Mount(top);
						retval = true;

					}						
				}
			}
		}else if(s.equalsIgnoreCase("cavegeneration")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				if(s.equalsIgnoreCase("true")){
					DangerZone.generatecaves = true;
				}else{
					DangerZone.generatecaves = false;
				}
				retval = true;
			}
		}else if(s.equalsIgnoreCase("playnicely")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				if(s.equalsIgnoreCase("true")){
					DangerZone.playnicely = true;
				}else{
					DangerZone.playnicely = false;
				}
				retval = true;
			}
		}else if(s.equalsIgnoreCase("validateplayers")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				if(s.equalsIgnoreCase("true")){
					DangerZone.require_valid_passwords = true;
				}else{
					DangerZone.require_valid_passwords = false;
				}
				retval = true;
			}
		}else if(s.equalsIgnoreCase("defaultprivs")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				int newdefprivs;
				try{
					newdefprivs = Integer.parseInt(s);
				}catch(NumberFormatException e){
					newdefprivs = 0;
				}
				DangerZone.default_privs = newdefprivs;
				retval = true;
			}
		}else if(s.equalsIgnoreCase("maxplayers")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				int newmaxplayers;
				try{
					newmaxplayers = Integer.parseInt(s);
				}catch(NumberFormatException e){
					newmaxplayers = 10;
				}
				if(newmaxplayers < 2 || newmaxplayers > 255)newmaxplayers = 10;
				DangerZone.max_players_on_server = newmaxplayers;
				retval = true;
			}
		}else if(s.equalsIgnoreCase("ban")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				DangerZone.server.setBanned(s, true);
				retval = true;
			}
		}else if(s.equalsIgnoreCase("unban")){
			if((pl.player_privs & PlayerPrivs.OPERATOR) == 0)return false;
			if(st.hasMoreTokens()){
				s = st.nextToken();
				DangerZone.server.setBanned(s, false);
				retval = true;
			}
		}

		return retval;
	}

}
