/* * This file is part of Matter Overdrive * Copyright (c) 2015., Simeon Radivoev, All rights reserved. * * Matter Overdrive is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Matter Overdrive is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Matter Overdrive. If not, see <http://www.gnu.org/licenses>. */ package matteroverdrive.starmap; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import cpw.mods.fml.common.gameevent.TickEvent; import matteroverdrive.MatterOverdrive; import matteroverdrive.api.starmap.GalacticPosition; import matteroverdrive.api.starmap.IBuilding; import matteroverdrive.api.starmap.IShip; import matteroverdrive.handler.ConfigurationHandler; import matteroverdrive.init.MatterOverdriveItems; import matteroverdrive.network.packet.client.starmap.PacketUpdateGalaxy; import matteroverdrive.network.packet.client.starmap.PacketUpdatePlanet; import matteroverdrive.starmap.data.*; import matteroverdrive.util.IConfigSubscriber; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.event.world.WorldEvent; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.UUID; /** * Created by Simeon on 6/17/2015. */ public class GalaxyServer extends GalaxyCommon implements IConfigSubscriber { //region Static Vars public static final int GALAXY_VERSION = 1; //endregion //region Private Vars private static GalaxyServer instance; private GalaxyGenerator galaxyGenerator; //endregion //region Constructors public GalaxyServer() { super(); galaxyGenerator = new GalaxyGenerator(); } //endregion //region Saving and Creation public void createGalaxy(File file,World world) { theGalaxy = galaxyGenerator.generateGalaxy("Galaxy",world.getWorldInfo().getVanillaDimension(),world.getWorldInfo().getSeed(),world); saveGalaxy(file); } public boolean saveGalaxy(File file) { try { if (!file.exists()) file.createNewFile(); FileOutputStream fileOutputStream = new FileOutputStream(file); NBTTagCompound tagCompound = new NBTTagCompound(); theGalaxy.writeToNBT(tagCompound); CompressedStreamTools.writeCompressed(tagCompound, fileOutputStream); fileOutputStream.close(); return true; } catch (IOException e) { MatterOverdrive.log.error("Galaxy could not be saved", e); return false; } } //endregion //region Loading public boolean loadGalaxy(File file,World world) { if (file.exists() && file.isFile()) { try { FileInputStream inputStream = new FileInputStream(file); NBTTagCompound tagCompound = CompressedStreamTools.readCompressed(inputStream); inputStream.close(); Galaxy theGalaxy = new Galaxy(world); theGalaxy.readFromNBT(tagCompound, galaxyGenerator); if (theGalaxy.getVersion() < GALAXY_VERSION) { MatterOverdrive.log.info("Galaxy Version is too old. Galaxy Needs regeneration"); galaxyGenerator.regenerateQuadrants(theGalaxy); } setTheGalaxy(theGalaxy); return true; } catch (IOException e) { MatterOverdrive.log.error("Could not load galaxy from file", e); return false; } }else { MatterOverdrive.log.info("Galaxy File could not be found at: '%s'", file); } return false; } //endregion /** * Claims a planet as the given players homeworld * @param player the player that claims the planet * @return The claimed planet. Null if none were claimed. */ private Planet claimPlanet(EntityPlayer player) { UUID playerUUID = EntityPlayer.func_146094_a(player.getGameProfile()); int quadrantID = random.nextInt(theGalaxy.getQuadrants().size()); for (Quadrant quadrant : theGalaxy.getQuadrants()) { if (quadrant.getId() == quadrantID) { for (Star star : quadrant.getStars()) { if (star.getPlanets().size() > 0) { boolean isClaimed = false; for (Planet planet : star.getPlanets()) { if (planet.hasOwner() && !planet.getOwnerUUID().equals(playerUUID)) { isClaimed = true; break; } } if (!isClaimed) { int planetID = random.nextInt(star.getPlanets().size()); Planet planet = (Planet) star.getPlanets().toArray()[planetID]; buildHomeworld(planet,player); return planet; } } } } } return null; } /** * Modifyes the planet to be a homeworld, by adding more fleet and building spaces * and building the starting buildings, such as a Base and a Ship Factory * @param planet The planet that will be transformed into a homeworld * @param player The player that will own the homeworld */ private void buildHomeworld(Planet planet,EntityPlayer player) { planet.setOwner(player); planet.setHomeworld(true); planet.setBuildingSpaces(8); planet.setFleetSpaces(10); ItemStack base = new ItemStack(MatterOverdriveItems.buildingBase); ((IBuilding)base.getItem()).setOwner(base,EntityPlayer.func_146094_a(player.getGameProfile())); planet.addBuilding(base); ItemStack scoutShip = new ItemStack(MatterOverdriveItems.scoutShip); ((IShip)scoutShip.getItem()).setOwner(scoutShip,EntityPlayer.func_146094_a(player.getGameProfile())); planet.addShip(scoutShip); planet.markDirty(); } /** * This function checks if a player already has a homeworld * and if not, then claims a random world and puts it in the homePlanets list * @param player The player that wants to claim a planet as their homeworld * @return if the player already has a world, returns false, if claiming was successful, returns true */ private boolean tryAndClaimPlanet(EntityPlayer player) { UUID playerUUID = EntityPlayer.func_146094_a(player.getGameProfile()); if (!homePlanets.containsKey(playerUUID)) { Planet claimedPlanet = claimPlanet(player); if (claimedPlanet != null) { homePlanets.put(playerUUID,claimedPlanet); return true; }else { MatterOverdrive.log.warn("%s could not claim planet.", player.getDisplayName()); } } return false; } /** * a Helper function that tries to create a travel event from one * Galactic Position to another, by checking if the event can be finished * and if so, then removes the ship from the source planet and puts it in the * travel event and returns the event itself * @param from The source planet position * @param to The Destination Planet position * @param shipID The Id of the ship. The id will be checked if valid * @return The Travel event if valid, and if not then returns null */ public TravelEvent createTravelEvent(GalacticPosition from,GalacticPosition to,int shipID) { Planet planet = theGalaxy.getPlanet(from); if (planet != null) { ItemStack ship = planet.getShip(shipID); if (ship != null) { TravelEvent travelEvent = new TravelEvent(world, from, to, ship, GalaxyServer.getInstance().getTheGalaxy()); if (travelEvent.isValid(GalaxyServer.getInstance().getTheGalaxy())) { if (GalaxyServer.getInstance().getTheGalaxy().canCompleteTravelEvent(travelEvent)) { theGalaxy.getPlanet(from).removeShip(shipID); theGalaxy.getPlanet(from).markDirty(); GalaxyServer.getInstance().getTheGalaxy().addTravelEvent(travelEvent); return travelEvent; } } } } return null; } //region Events @SubscribeEvent public void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) { if (!event.player.worldObj.isRemote) { if (theGalaxy != null) { MatterOverdrive.packetPipeline.sendTo(new PacketUpdateGalaxy(theGalaxy), (EntityPlayerMP) event.player); if (tryAndClaimPlanet(event.player)) { Planet planet = getHomeworld(event.player); MatterOverdrive.packetPipeline.sendToDimention(new PacketUpdatePlanet(planet), event.player.worldObj); } }else { MatterOverdrive.log.warn("Galaxy is missing."); } } } @SubscribeEvent public void onWorldLoad(WorldEvent.Load load) { if (!load.world.isRemote && load.world.provider.dimensionId == 0) { world = load.world; File galaxyFile = getGalaxyFile(load.world); long start = System.nanoTime(); if (!loadGalaxy(galaxyFile,load.world)) { createGalaxy(galaxyFile, load.world); MatterOverdrive.log.info("Galaxy Generated and saved to '%1$s'. Took %2$s milliseconds", galaxyFile.getPath(), ((System.nanoTime() - start) / 1000000)); }else { MatterOverdrive.log.info("Galaxy Loaded from '%1$s'. Took %2$s milliseconds", galaxyFile.getPath(), ((System.nanoTime() - start) / 1000000)); } } } @SubscribeEvent public void onWorldSave(WorldEvent.Save save) { if (save.world == null || theGalaxy == null) return; if (!save.world.isRemote && save.world.provider.dimensionId == 0) { if (theGalaxy.isDirty()) { long start = System.nanoTime(); File galaxyFile = getGalaxyFile(save.world); if (saveGalaxy(galaxyFile)) { theGalaxy.onSave(galaxyFile,save.world); MatterOverdrive.log.info("Galaxy saved to '%s'. Took %s milliseconds", galaxyFile.getPath(), ((System.nanoTime() - start) / 1000000)); } } } } @SubscribeEvent public void onWorldUnload(WorldEvent.Unload unload) { if (unload.world == null || theGalaxy == null) return; if (unload.world.isRemote && unload.world.provider.dimensionId == 0) { this.world = null; theGalaxy = null; homePlanets.clear(); } } @SubscribeEvent public void onWorldTick(TickEvent.WorldTickEvent event) { if (event.world == null || theGalaxy == null) return; if (!event.world.isRemote && event.world.provider.dimensionId == 0) { theGalaxy.update(event.world); } } @Override public void onConfigChanged(ConfigurationHandler config) { Galaxy.GALAXY_BUILD_TIME_MULTIPLY = config.config.getFloat("galaxy build time multiply",ConfigurationHandler.CATEGORY_STARMAP,1,0,10,"The multiplier for the building and ship building times"); Galaxy.GALAXY_TRAVEL_TIME_MULTIPLY = config.config.getFloat("galaxy travel time multiply",ConfigurationHandler.CATEGORY_STARMAP,1,0,10,"The multiplier for the ship travel times"); } //endregion //region Getters and Setters private File getGalaxyFile(World world) { File worldDirectory = world.getSaveHandler().getWorldDirectory(); return new File(worldDirectory.getPath() + "/galaxy.dat"); } public GalaxyGenerator getGalaxyGenerator(){return galaxyGenerator;} public static GalaxyServer getInstance() { if (instance == null) { instance = new GalaxyServer(); } return instance; } //endregion }