Changeset 5c543f001f919169bbf0d7061b41bcb97c58c70e

Show
Ignore:
Timestamp:
12/31/06 23:23:41 (2 years ago)
Author:
Christopher Jung <bktheg@web.de>
git-committer:
Christopher Jung <bktheg@web.de> 1167603821 +0100
git-parent:

[06e48acb855ee3cb7f8f6b91da60c5c622ac20d0]

git-author:
Christopher Jung <bktheg@web.de> 1167603821 +0100
Message:

KS-Lib in Teilen implementiert

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/net/driftingsouls/ds2/server/battles/Battle.java

    r4152e61 r5c543f0  
    1919package net.driftingsouls.ds2.server.battles; 
    2020 
     21import java.io.BufferedWriter; 
     22import java.io.File; 
     23import java.io.FileWriter; 
     24import java.io.IOException; 
     25import java.util.ArrayList; 
     26import java.util.HashMap; 
     27import java.util.HashSet; 
     28import java.util.List; 
     29import java.util.Map; 
     30import java.util.Set; 
     31 
     32import org.apache.commons.lang.StringUtils; 
     33import org.apache.commons.lang.SystemUtils; 
     34 
     35import net.driftingsouls.ds2.server.ContextCommon; 
     36import net.driftingsouls.ds2.server.Location; 
     37import net.driftingsouls.ds2.server.framework.Common; 
     38import net.driftingsouls.ds2.server.framework.Configuration; 
     39import net.driftingsouls.ds2.server.framework.Context; 
     40import net.driftingsouls.ds2.server.framework.ContextMap; 
     41import net.driftingsouls.ds2.server.framework.Loggable; 
     42import net.driftingsouls.ds2.server.framework.User; 
     43import net.driftingsouls.ds2.server.framework.db.Database; 
     44import net.driftingsouls.ds2.server.framework.db.PreparedQuery; 
     45import net.driftingsouls.ds2.server.framework.db.SQLQuery; 
    2146import net.driftingsouls.ds2.server.framework.db.SQLResultRow; 
     47import net.driftingsouls.ds2.server.ships.Ships; 
     48import net.driftingsouls.ds2.server.ships.ShipClasses; 
    2249 
    2350/** 
     
    2653 * 
    2754 */ 
    28 public class Battle { 
     55public class Battle implements Loggable { 
     56        private static final int LOGFORMAT = 2; 
     57         
    2958        // 
    3059        // Aktionskonstanten von Schiffen in der Schlacht (battles_ships->action) 
     
    98127        private int system = 0; 
    99128        private int flags = 0; 
     129        private String ownShipGroup = "0"; 
     130        private String enemyShipGroup = "0"; 
     131         
     132        private int ownSide = 0; 
     133        private int enemySide = 0; 
     134         
     135        private List<SQLResultRow> ownShips = new ArrayList<SQLResultRow>(); 
     136        private List<SQLResultRow> enemyShips = new ArrayList<SQLResultRow>(); 
     137         
     138        private boolean startOwn = false; 
     139 
     140        private int[] points = new int[2]; 
     141        private int[] ally = new int[2]; 
     142        private int[] commander = new int[2]; 
     143        private boolean[] ready = new boolean[2]; 
     144        private String[] comMsg = new String[2]; 
     145        private boolean[] betak = new boolean[2]; 
     146        private int[] takeCommand = new int[2]; 
     147        private List<List<Integer>> addCommanders = new ArrayList<List<Integer>>(); 
     148         
     149        private int blockcount = 0; 
     150        private int lastturn = 0; 
     151        private String visibility = ""; 
     152        private int quest = 0; 
     153        private boolean guest = false; 
     154         
     155        private SQLResultRow tableBuffer = null; 
     156         
     157        private Map<Integer,Integer> ownShipTypeCount = new HashMap<Integer,Integer>(); 
     158        private Map<Integer,Integer> enemyShipTypeCount = new HashMap<Integer,Integer>(); 
     159         
     160        private int activeSOwn = 0; 
     161        private int activeSEnemy = 0; 
     162         
     163        private StringBuilder logoutputbuffer = new StringBuilder(); 
     164        private StringBuilder logenemybuffer = new StringBuilder(); 
    100165         
    101166        /** 
     
    131196        } 
    132197         
     198        /** 
     199         * Prueft, ob die zweite Reihe stabil ist. Beruecksichtigt wird auf Wunsch  
     200         * auch eine Liste von Schiffen, welche der Schlacht noch nicht begetreten sind 
     201         * (unter der Annahme, dass gemaess Flags die Schiffe in der ersten bzw zweiten 
     202         * Reihe landen wuerden). 
     203         * @param side Die Seite deren zweite Reihe geprueft werden soll 
     204         * @param added Eine Liste zusaetzlicher Schiffe, welche sich noch nicht in der Schlacht befinden oder <code>null</code> 
     205         * @return <code>true</code>, falls die zweite Reihe unter den Bedingungen stabil ist 
     206         */ 
    133207        public boolean isSecondRowStable( int side, SQLResultRow[] added ) { 
    134                 throw new RuntimeException("STUB"); 
     208                List<SQLResultRow> shiplist = null; 
     209                if( side == this.ownSide ) { 
     210                        shiplist = this.ownShips; 
     211                } 
     212                else { 
     213                        shiplist = this.enemyShips; 
     214                } 
     215                 
     216                int owncaps = 0; 
     217                int secondrowcaps = 0; 
     218                for( int i=0; i < shiplist.size(); i++ ) { 
     219                        SQLResultRow aship = shiplist.get(i); 
     220                         
     221                        if( (aship.getInt("action") & BS_JOIN) != 0 || (aship.getInt("action") & BS_FLUCHT) != 0 ) { 
     222                                continue;        
     223                        } 
     224                        SQLResultRow type = Ships.getShipType(aship); 
     225                         
     226                        if( (aship.getInt("action") & BS_SECONDROW) != 0 ) { 
     227                                if( aship.getString("docked").length() == 0 ) { 
     228                                        secondrowcaps += type.getInt("size"); 
     229                                } 
     230                        } 
     231                        else if( type.getInt("size") > 3 ) { 
     232                                owncaps += type.getInt("size");  
     233                        }        
     234                } 
     235                 
     236                if( added != null ) { 
     237                        for( int i=0; i < added.length; i++ ) { 
     238                                SQLResultRow aship = added[i]; 
     239                                 
     240                                SQLResultRow type = Ships.getShipType(aship); 
     241                                 
     242                                if( !Ships.hasShipTypeFlag(type, Ships.SF_SECONDROW) ) { 
     243                                        continue; 
     244                                } 
     245                                 
     246                                if( aship.getString("docked").length() == 0 ) { 
     247                                        secondrowcaps += type.getInt("size"); 
     248                                }        
     249                        } 
     250                } 
     251 
     252                if( secondrowcaps == 0 ) { 
     253                        return true;     
     254                } 
     255                                 
     256                if( owncaps <= secondrowcaps*2 ) { 
     257                        return false; 
     258                } 
     259                return true; 
    135260        } 
    136261         
     
    166291        } 
    167292         
     293        /** 
     294         * Fuegt dem Nachrichtenpuffer einer Seite eine Nachricht hinzu 
     295         * @param side Die Seite 
     296         * @param text Der hinzuzufuegende Text 
     297         */ 
    168298        public void addComMessage( int side, String text ) { 
    169299                throw new RuntimeException("STUB"); 
    170300        } 
    171301         
     302        /** 
     303         * Leert den Nachrichtenpuffer fuer die angegebene Seite 
     304         * @param side Die Seite oder <code>-1</code> fuer die eigene Seite 
     305         */ 
    172306        public void clearComMessageBuffer( int side ) { 
    173                 throw new RuntimeException("STUB"); 
    174         } 
    175          
    176         public void getComMessageBuffer( int side ) { 
    177                 throw new RuntimeException("STUB"); 
    178         } 
    179          
     307                if( side == -1 ) { 
     308                        side = this.ownSide; 
     309                } 
     310                Database db = ContextMap.getContext().getDatabase(); 
     311                 
     312                db.update("UPDATE battles SET com",(side+1),"Msg='' WHERE id=",this.id); 
     313                comMsg[side] = ""; 
     314        } 
     315         
     316        /** 
     317         * Gibt den Inhalt des Nachrichtenpuffers der angegebenen Seite zurueck 
     318         * @param side Die Seite 
     319         * @return Der Nachrichtenpuffer 
     320         */ 
     321        public String getComMessageBuffer( int side ) { 
     322                return this.comMsg[side]; 
     323        } 
     324         
     325        private int getActionPoints( int side ) { 
     326                List<SQLResultRow> olist = this.ownShips; 
     327                List<SQLResultRow> elist = this.enemyShips; 
     328                 
     329                if( side != this.ownSide ) { 
     330                        elist = this.ownShips; 
     331                        olist = this.enemyShips; 
     332                } 
     333                 
     334                double points = 600; 
     335                 
     336                double ownsize = 0; 
     337                int owncount = 0; 
     338                double enemysize = 0; 
     339                int enemycount = 0; 
     340                 
     341                for( int i=0; i < olist.size(); i++ ) { 
     342                        SQLResultRow aShip = olist.get(i); 
     343                         
     344                        SQLResultRow aShipType = Ships.getShipType(aShip); 
     345                        if( (aShipType.getInt("size") > 3) && (aShipType.getInt("military") != 0) && (aShipType.getInt("crew") > 0) ) { 
     346                                double factor = aShip.getInt("crew") / (double)aShipType.getInt("crew"); 
     347                                ownsize += factor*aShipType.getInt("size"); 
     348                                owncount++; 
     349                        } 
     350                }        
     351                 
     352                for( int i=0; i < elist.size(); i++ ) { 
     353                        SQLResultRow aShip = elist.get(i); 
     354                         
     355                        SQLResultRow aShipType = Ships.getShipType(aShip); 
     356                        if( (aShipType.getInt("size") > 3) && (aShipType.getInt("military") != 0) && (aShipType.getInt("crew") > 0) ) { 
     357                                double factor = aShip.getInt("crew") / (double)aShipType.getInt("crew"); 
     358                                enemysize += factor*aShipType.getInt("size"); 
     359                                enemycount++; 
     360                        } 
     361                }        
     362                 
     363                if( enemycount > 0 ) { 
     364                        if( enemysize < 1 ) { 
     365                                enemysize = 1; 
     366                        } 
     367                        if( ownsize > enemysize ) { 
     368                                points += (ownsize/enemysize-1 > 1 ? 1 : ownsize/enemysize-1)*points;    
     369                        } 
     370                } 
     371                else { 
     372                        int add = owncount*2; 
     373                        if( add > 100 ) { 
     374                                add = 100; 
     375                        } 
     376                        points += points*add/100; 
     377                }                
     378                 
     379                return (int)Math.round(points); 
     380        } 
     381         
     382        /** 
     383         * Bestimmt, ob eigene gelandete Schiffe beim Start der Schlacht starten sollen 
     384         * @param value <code>true</code>, falls eigene gelandete Schiffe starten sollen 
     385         */ 
    180386        public void setStartOwn( boolean value ) { 
    181                 throw new RuntimeException("STUB"); 
    182         } 
    183          
     387                this.startOwn = value;   
     388        } 
     389         
     390        /** 
     391         * Gibt den Betak-Status einer Seite zurueck 
     392         * @param side Die Seite 
     393         * @return <code>true</code>, falls die Seite noch nicht gegen die Betak verstossen hat 
     394         */ 
    184395        public boolean getBetakStatus( int side ) { 
    185                 throw new RuntimeException("STUB"); 
    186         } 
    187          
     396                return this.betak[side];         
     397        } 
     398         
     399        /** 
     400         * Setzt den Betak-Status einer Seite 
     401         * @param side Die Seite 
     402         * @param status Der neue Betak-Status 
     403         */ 
    188404        public void setBetakStatus( int side, boolean status ) { 
    189                 throw new RuntimeException("STUB"); 
    190         } 
    191          
     405                this.betak[side] = status; 
     406        } 
     407         
     408        /** 
     409         * Prueft, ob der Betrachter ein Gast ist 
     410         * @return <code>true</code>, falls der Betrachter ein Gast ist 
     411         */ 
    192412        public boolean isGuest() { 
    193                 throw new RuntimeException("STUB");      
    194         } 
    195  
     413                return this.guest;       
     414        } 
     415 
     416        /** 
     417         * Gibt das aktuell ausgewaehlte eigene Schiff zurueck 
     418         * @return Das aktuell ausgewaehlte eigene Schiff 
     419         */ 
    196420        public SQLResultRow getOwnShip() { 
    197                 throw new RuntimeException("STUB"); 
    198         } 
    199  
     421                return this.ownShips.get(this.activeSOwn); 
     422        } 
     423 
     424        /** 
     425         * Gibt das aktuell ausgewaehlte gegnerische Schiff zurueck 
     426         * @return Das aktuell ausgewaehlte gegnerische Schiff 
     427         */ 
    200428        public SQLResultRow getEnemyShip() { 
    201                 throw new RuntimeException("STUB"); 
    202         } 
    203          
     429                return this.enemyShips.get(this.activeSEnemy); 
     430        } 
     431         
     432        @Deprecated 
    204433        public void syncOwnShip(SQLResultRow ownShip) { 
    205434                throw new RuntimeException("STUB"); 
    206435        } 
    207436         
     437        @Deprecated 
    208438        public void syncEnemyShip(SQLResultRow enemyShip) { 
    209439                throw new RuntimeException("STUB"); 
     
    216446        //---------------------------------------- 
    217447 
     448        /** 
     449         * Speichert die aktuellen Aenderungen in der Schlacht in der Datenbank 
     450         * @param ignoreinakt Soll das Inaktivitaetsfeld nicht zurueckgesetzt werden (<code>true</code>)? 
     451         */ 
    218452        public void save( boolean ignoreinakt  ) { 
    219453                throw new RuntimeException("STUB"); 
     
    226460        //---------------------------------------- 
    227461 
    228         public void create( int id, int ownShipID, int enemyShipID ) { 
     462        /** 
     463         * Erstellt eine neue Schlacht 
     464         * @param id Die ID des Spielers, der die Schlacht beginnt 
     465         * @param ownShipID Die ID des Schiffes des Spielers, der angreift 
     466         * @param enemyShipID Die ID des angegriffenen Schiffes 
     467         * @return <code>true</code>, falls die Schlacht erfolgreich erstellt wurde 
     468         */ 
     469        public boolean create( int id, int ownShipID, int enemyShipID ) { 
     470                Context context = ContextMap.getContext(); 
     471                Database db = context.getDatabase(); 
     472                 
     473                // Kann der Spieler ueberhaupt angreifen (Noob-Schutz?) 
     474                User user = context.createUserObject( id ); 
     475                if( user.isNoob() ) { 
     476                        context.addError("Sie stehen unter GCP-Schutz und k&ouml;nnen daher keinen Gegner angreifen!<br />Hinweis: der GCP-Schutz kann unter Optionen vorzeitig beendet werden"); 
     477                        return false; 
     478                } 
     479                 
     480                SQLResultRow tmpOwnShip = db.first("SELECT t1.id,t1.x,t1.y,t1.system,t2.ally,t1.lock FROM ships t1 JOIN users t2 ON t1.owner=t2.id WHERE t1.id>0 AND t1.owner=",id," AND t1.id=",ownShipID); 
     481                SQLResultRow tmpEnemyShip = db.first("SELECT t1.id,t1.x,t1.y,t1.system,t1.owner,t1.status,t2.ally,t1.lock FROM ships t1 JOIN users t2 ON t1.owner=t2.id WHERE t1.id>0 AND t1.id=",enemyShipID); 
     482 
     483                if( tmpOwnShip.isEmpty() ) { 
     484                        context.addError("Das angreifende Schiff existiert nicht oder untersteht nicht ihrem Kommando!"); 
     485                        return false; 
     486                } 
     487                 
     488                if( tmpEnemyShip.isEmpty() ) { 
     489                        context.addError("Das angegebene Zielschiff existiert nicht!"); 
     490                        return false; 
     491                } 
     492                 
     493                if( !Location.fromResult(tmpOwnShip).sameSector(0,Location.fromResult(tmpEnemyShip),0) ) { 
     494                        context.addError("Die beiden Schiffe befinden sich nicht im selben Sektor"); 
     495                        return false; 
     496                } 
     497 
     498                // 
     499                // Kann der Spieler angegriffen werden (NOOB-Schutz?/Vac-Mode?) 
     500                // 
     501 
     502                User enemyUser = context.createUserObject( tmpEnemyShip.getInt("owner") ); 
     503                if( enemyUser.isNoob() ) { 
     504                        context.addError("Der Gegner steht unter GCP-Schutz und kann daher nicht angegriffen werden!"); 
     505                        return false; 
     506                } 
     507                 
     508                if( enemyUser.getVacationCount() != 0 && enemyUser.getWait4VacationCount() == 0 ) { 
     509                        context.addError("Der Gegner befindet sich im Vacation-Modus und kann daher nicht angegriffen werden!"); 
     510                        return false; 
     511                } 
     512                 
     513                // 
     514                // IFF-Stoersender? 
     515                //  
     516                boolean disable_iff = tmpEnemyShip.getString("status").indexOf("disable_iff") > -1; 
     517                if( disable_iff ) { 
     518                        context.addError("Dieses Schiff kann nicht angegriffen werden (egal wieviel du mit der URL rumspielt!)"); 
     519                        return false;    
     520                } 
     521                 
     522                // 
     523                // Questlock? 
     524                //  
     525                if( tmpOwnShip.getString("lock").length() > 0 ) { 
     526                        context.addError("Ihr Schiff ist an ein Quest gebunden"); 
     527                        return false; 
     528                } 
     529                 
     530                if( tmpEnemyShip.getString("lock").length() > 0 ) { 
     531                        context.addError("Das gegnerische Schiff ist an ein Quest gebunden"); 
     532                        return false; 
     533                } 
     534 
     535                // 
     536                // Schiffsliste zusammenstellen 
     537                // 
     538                 
     539                this.ownSide = 0; 
     540                this.enemySide = 1; 
     541                 
     542                SQLResultRow enemyShip = new SQLResultRow(); 
     543                SQLResultRow ownShip = new SQLResultRow(); 
     544                 
     545                Set<Integer> ownUsers = new HashSet<Integer>(); 
     546                Set<Integer> enemyUsers = new HashSet<Integer>();                
     547         
     548                SQLQuery aShipRow = db.query("SELECT t1.*,t2.name AS username,t2.ally ", 
     549                                                                        "FROM ships t1 JOIN users t2 ON t1.owner=t2.id ", 
     550                                                                        "WHERE t1.id>0 AND t1.x=",tmpOwnShip.getInt("x")," AND t1.y=",tmpOwnShip.getInt("y")," AND " , 
     551                                                                                "t1.system=",tmpOwnShip.getInt("system")," AND t1.battle=0 AND " , 
     552                                                                                "t2.ally IN (",tmpOwnShip.getInt("ally"),",",tmpEnemyShip.getInt("ally"),") AND " , 
     553                                                                                "!LOCATE('disable_iff',t1.status)"); 
     554                                                                         
     555                while( aShipRow.next() ) { 
     556                        if( (aShipRow.getString("lock") != null) && aShipRow.getString("lock").length() > 0 ) { 
     557                                continue;        
     558                        } 
     559                        // Loot-Truemmer sollten in keine Schlacht wandern... (nicht schoen, gar nicht schoen geloest) 
     560                        if( (aShipRow.getInt("owner") == -1) && (aShipRow.getInt("type") == Configuration.getIntSetting("CONFIG_TRUEMMER")) ) { 
     561                                continue; 
     562                        } 
     563                         
     564                        User tmpUser = context.createUserObject( aShipRow.getInt("owner") ); 
     565                                                 
     566                        if( ((tmpUser.getVacationCount() != 0) && (tmpUser.getWait4VacationCount() == 0)) || tmpUser.isNoob() ) { 
     567                                continue; 
     568                        } 
     569                         
     570                        SQLResultRow aShip = aShipRow.getRow(); 
     571                         
     572                        SQLResultRow shiptype = Ships.getShipType(aShip); 
     573                        if( (aShip.getString("docked").length() == 0) && Ships.hasShipTypeFlag(shiptype, Ships.SF_SECONDROW) ) { 
     574                                aShip.put("action", BS_SECONDROW); 
     575                        } 
     576                        else { 
     577                                aShip.put("action", 0); 
     578                        } 
     579                         
     580                        if( (shiptype.getInt("class") == ShipClasses.GESCHUETZ.ordinal()) && aShip.getString("docked").length() > 0 ) { 
     581                                aShip.put("action", aShip.getInt("action") | BS_DISABLE_WEAPONS); 
     582                        } 
     583                         
     584                        if( ( (tmpOwnShip.getInt("ally") > 0) && (aShip.getInt("ally") == tmpOwnShip.getInt("ally")) ) || (id == aShip.getInt("owner")) ) { 
     585                                ownUsers.add(aShip.getInt("owner")); 
     586                                if( (ownShipID != 0) && (aShip.getInt("id") == ownShipID) ) { 
     587                                        ownShip = aShip; 
     588                                }  
     589                                else { 
     590                                        this.ownShips.add(aShip); 
     591                                } 
     592                        }  
     593                        else if( ( (tmpEnemyShip.getInt("ally") > 0) && (aShip.getInt("ally") == tmpEnemyShip.getInt("ally")) ) || (tmpEnemyShip.getInt("owner") == aShip.getInt("owner")) ) { 
     594                                enemyUsers.add(aShip.getInt("owner")); 
     595                                if( (enemyShipID != 0) && (aShip.getInt("id") == enemyShipID) ) { 
     596                                        enemyShip = aShip; 
     597                                }  
     598                                else { 
     599                                        this.enemyShips.add(aShip); 
     600                                } 
     601                        } 
     602 
     603                } 
     604                aShipRow.free(); 
     605                 
     606                tmpOwnShip.clear(); 
     607                tmpEnemyShip.clear(); 
     608 
     609                // 
     610                // Schauen wir mal ob wir was sinnvolles aus der DB gelesen haben 
     611                // - Wenn nicht: Abbrechen 
     612                // 
     613                 
     614                if( ownShip.isEmpty() ) { 
     615                        context.addError("Offenbar liegt ein Problem mit dem von ihnen angegebenen Schiff oder ihrem eigenen Schiff vor (wird es evt. bereits angegriffen?)"); 
     616                        return false; 
     617                } 
     618                 
     619                if( enemyShip.isEmpty() && (enemyShips.size() == 0) ) { 
     620                        context.addError("Offenbar liegt ein Problem mit den feindlichen Schiffen vor (es gibt n&aumlmlich keine die sie angreifen k&ouml;nnten)"); 
     621                        return false; 
     622                } 
     623                else if( enemyShip.isEmpty() ) { 
     624                        context.addError("Offenbar liegt ein Problem mit den feindlichen Schiffen vor (es gibt zwar welche, jedoch fehlt das Zielschiff)"); 
     625                        return false; 
     626                } 
     627                 
     628                // 
     629                // Schlacht in die DB einfuegen 
     630                // 
     631 
     632                db.update("INSERT INTO battles (x,y,system,ally1,ally2,commander1,com1Points,commander2,com2Points,lastaction,lastturn,flags) ", 
     633                                                        "VALUES (",ownShip.getInt("x"),",",ownShip.getInt("y"),",",ownShip.getInt("system"),",",ownShip.getInt("ally"),",",enemyShip.getInt("ally"),", ", 
     634                                                        ownShip.getInt("owner"),",0,",enemyShip.getInt("owner"),",0,",Common.time(),",",Common.time(),",'",FLAG_FIRSTROUND,"')"); 
     635                this.id = db.insertID(); 
     636 
     637                if( db.affectedRows() == 0 ) { 
     638                        context.addError("<span style=\"color:red\">Die Schlacht konnte nicht erfolgreich erstellt werden</span>"); 
     639                        return false; 
     640                } 
     641 
     642                // 
     643                // Schiffe in die Schlacht einfuegen 
     644                // 
     645 
     646                int tick = context.get(ContextCommon.class).getTick(); 
     647 
     648                // * Gegnerische Schiffe in die Schlacht einfuegen 
     649                List<Integer> idlist = new ArrayList<Integer>(); 
     650                List<Integer> startlist = new ArrayList<Integer>(); 
     651 
     652                if( (enemyShip.getString("docked").length() > 0) && (enemyShip.getString("docked").charAt(0) == 'l') ) { 
     653                        startlist.add(enemyShip.getInt("id")); 
     654                } 
     655                idlist.add(enemyShip.getInt("id")); 
     656                 
     657                SQLResultRow enemyShipType = Ships.getShipType(enemyShip); 
     658 
     659                db.update("INSERT INTO battles_ships ", 
     660                                        "(shipid,battleid,side,hull,shields,engine,weapons,comm,sensors,action,count) ", 
     661                                        "VALUES (",enemyShip.getInt("id"),",",this.id,",1,",enemyShip.getInt("hull"),",",enemyShip.getInt("shields"),",",enemyShip.getInt("engine"),",",enemyShip.getInt("weapons"),",",enemyShip.getInt("comm"),",",enemyShip.getInt("sensors"),",",enemyShip.getInt("action"),",",enemyShipType.getInt("shipcount"),")"); 
     662 
     663 
     664                for( int i=0; i < enemyShips.size(); i++ ) { 
     665                        SQLResultRow ship = enemyShips.get(i); 
     666                         
     667                        if( (ship.getString("docked").length() > 0) &&  
     668                                (ship.getString("docked").charAt(0) == 'l') ) { 
     669                                startlist.add(ship.getInt("id")); 
     670                        } 
     671                        idlist.add(ship.getInt("id")); 
     672                         
     673                        SQLResultRow shiptype = Ships.getShipType(ship); 
     674 
     675                        db.update("INSERT INTO battles_ships ", 
     676                                        "(shipid,battleid,side,hull,shields,engine,weapons,comm,sensors,action,count) ", 
     677                                        "VALUES (",ship.getInt("id"),",",this.id,",1,",ship.getInt("hull"),",",ship.getInt("shields"),",",ship.getInt("engine"),",",ship.getInt("weapons"),",",ship.getInt("comm"),",",ship.getInt("sensors"),",",ship.getInt("action"),",",shiptype.getInt("shipcount"),")"); 
     678                } 
     679                if( startlist.size() > 0 ) { 
     680                        this.logme(startlist.size()+" J&auml;ger sind automatisch gestartet\n"); 
     681                        this.logenemy("<action side=\"1\" time=\""+Common.time()+"\" tick=\""+tick+"\"><![CDATA[\n"+startlist.size()+" J&auml;ger sind automatisch gestartet\n]]></action>\n"); 
     682 
     683                        db.update("UPDATE ships SET docked='' WHERE id>0 AND id IN ("+Common.implode(",",startlist),")"); 
     684                        startlist.clear(); 
     685                } 
     686 
     687                // * Eigene Schiffe in die Schlacht einfuegen 
     688                idlist.add(ownShip.getInt("id")); 
     689                 
     690                SQLResultRow ownShipType = Ships.getShipType(ownShip); 
     691 
     692                db.update("INSERT INTO battles_ships ", 
     693                                "(shipid,battleid,side,hull,shields,engine,weapons,comm,sensors,action,count) ", 
     694                                "VALUES (",ownShip.getInt("id"),",",this.id,",0,",ownShip.getInt("hull"),",",ownShip.getInt("shields"),",",ownShip.getInt("engine"),",",ownShip.getInt("weapons"),",",ownShip.getInt("comm"),",",ownShip.getInt("sensors"),",",ownShip.getInt("action"),",",ownShipType.getInt("shipcount"),")"); 
     695 
     696                for( int i=0; i < ownShips.size(); i++ ) { 
     697                        SQLResultRow ship = ownShips.get(i); 
     698                         
     699                        if( this.startOwn && (ship.getString("docked").length() > 0) &&  
     700                                (ship.getString("docked").charAt(0) == 'l') ) { 
     701                                startlist.add(ship.getInt("id")); 
     702                        } 
     703                        idlist.add(ship.getInt("id")); 
     704                         
     705                        SQLResultRow shiptype = Ships.getShipType(ship); 
     706 
     707                        db.update("INSERT INTO battles_ships ", 
     708                                        "(shipid,battleid,side,hull,shields,engine,weapons,comm,sensors,action,count) ", 
     709                                        "VALUES (",ship.getInt("id"),",",this.id,",0,",ship.getInt("hull"),",",ship.getInt("shields"),",",ship.getInt("engine"),",",ship.getInt("weapons"),",",ship.getInt("comm"),",",ship.getInt("sensors"),",",ship.getInt("action"),",",shiptype.getInt("shipcount"),")"); 
     710                } 
     711                if( this.startOwn && startlist.size() > 0 ) { 
     712                        this.logme(startlist.size()+" J&auml;ger sind automatisch gestartet\n"); 
     713                        this.logenemy("<action side=\"0\" time=\""+Common.time()+"\" tick=\""+tick+"\"><![CDATA[\n"+startlist.size()+" J&auml;ger sind automatisch gestartet\n]]></action>\n"); 
     714 
     715                        db.update("UPDATE ships SET docked='' WHERE id>0 AND id IN ("+Common.implode(",",startlist),")"); 
     716                } 
     717                startlist = null; 
     718 
     719                db.update("UPDATE ships SET battle=",this.id," WHERE id>0 AND id IN (",Common.implode(",",idlist),")"); 
     720                idlist = null; 
     721 
     722                // 
     723                // Log erstellen 
     724                // 
     725 
     726                try { 
     727                        BufferedWriter writer = new BufferedWriter(new FileWriter(Configuration.getSetting("LOXPATH")+"battles/battle_id"+this.id+".log")); 
     728                        writer.append("<?xml version='1.0' encoding='UTF-8'?>\n"); 
     729                        writer.append("<battle>\n"); 
     730                        writer.append("<fileinfo format=\""+LOGFORMAT+"\" />\n"); 
     731                        writer.append("<coords x=\""+ownShip.getInt("x")+"\" y=\""+ownShip.getInt("y")+"\" system=\""+ownShip.getInt("system")+"\" />\n"); 
     732         
     733                        if( ownShip.getInt("ally") > 0 ) { 
     734                                writer.append("<side1 commander=\""+ownShip.getInt("owner")+"\" ally=\""+ownShip.getInt("ally")+"\" />\n"); 
     735                        } 
     736                        else { 
     737                                writer.append("<side1 commander=\""+ownShip.getInt("owner")+"\" />\n"); 
     738                        } 
     739         
     740                        if( enemyShip.getInt("ally") > 0 ) { 
     741                                writer.append("<side2 commander=\""+enemyShip.getInt("owner")+"\" ally=\""+enemyShip.getInt("ally")+"\" />\n"); 
     742                        } 
     743                        else { 
     744                                writer.append("<side2 commander=\""+enemyShip.getInt("owner")+"\" />\n"); 
     745                        } 
     746         
     747                        writer.append("<startdate tick=\"$tick\" time=\""+Common.time()+"\" />\n"); 
     748                        writer.close(); 
     749                         
     750                        if( SystemUtils.IS_OS_UNIX ) { 
     751                                Runtime.getRuntime().exec("chmod 0666 "+Configuration.getSetting("LOXPATH")+"battles/battle_id"+this.id+".log"); 
     752                        } 
     753                } 
     754                catch( IOException e ) { 
     755                        LOG.error("Konnte KS-Log fuer Schlacht "+this.id+" nicht erstellen", e); 
     756                } 
     757                 
     758                 
     759                // 
     760                // Beziehungen aktuallisieren 
     761                // 
     762                 
     763                // Zuerst schauen wir mal ob wir es mit Allys zu tun haben und  
     764                // berechnen ggf die Userlisten neu  
     765                Set<Integer> calcedallys = new HashSet<Integer>(); 
     766                 
     767                for( Integer auserID : ownUsers ) { 
     768                        User auser = context.createUserObject(auserID); 
     769                         
     770                        if( (auser.getAlly() != 0) && calcedallys.contains(auser.getAlly()) ) {          
     771                                SQLQuery allyuser = db.query("SELECT id FROM users WHERE ally=",auser.getAlly()," AND !(id IN (",Common.implode(",",ownUsers),"))"); 
     772                                while( allyuser.next() ) { 
     773                                        ownUsers.add(allyuser.getInt("id"));     
     774                                } 
     775                                calcedallys.add(auser.getAlly()); 
     776                        } 
     777                } 
     778 
     779                for( Integer auserID : enemyUsers ) { 
     780                        User auser = context.createUserObject(auserID); 
     781                         
     782                        if( (auser.getAlly() != 0) && calcedallys.contains(auser.getAlly()) ) {          
     783                                SQLQuery allyuser = db.query("SELECT id FROM users WHERE ally=",auser.getAlly()," AND !(id IN (",Common.implode(",",enemyUsers),"))"); 
     784                                while( allyuser.next() ) { 
     785                                        enemyUsers.add(allyuser.getInt("id"));   
     786                                } 
     787                                calcedallys.add(auser.getAlly()); 
     788                        } 
     789                } 
     790                calcedallys = null; 
     791                 
     792                for( Integer auserID : ownUsers ) { 
     793                        User auser = context.createUserObject(auserID); 
     794                         
     795                        for( Integer euserID : enemyUsers ) { 
     796                                User euser = context.createUserObject(euserID); 
     797                                                                 
     798                                auser.setRelation(euser.getID(), User.Relation.ENEMY); 
     799                                euser.setRelation(auser.getID(), User.Relation.ENEMY); 
     800                        } 
     801                } 
     802                 
     803                // 
     804                // APs berechnen 
     805                // 
     806 
     807                 
     808                // Zuerst berechnen wir die eigenen AP 
     809                int ownPoints = this.getActionPoints(this.ownSide); 
     810 
     811                // Nun berechnen wir die gegnerischen AP  
     812                int enemyPoints = this.getActionPoints(this.enemySide); 
     813                 
     814                db.update("UPDATE battles SET com1Points=",ownPoints,",com2Points=",enemyPoints," WHERE id=",this.id); 
     815                 
     816                return true; 
     817        } 
     818         
     819        //--------------------------------------------------------------------- 
     820        // 
     821        // addShip - Ein Schiff oder eine Flotte zu der Schlacht hinzufuegen 
     822        // 
     823        //--------------------------------------------------------------------- 
     824 
     825        public boolean addShip( int id, int shipid ) { 
     826                return addShip(id, shipid, -1); 
     827        } 
     828         
     829        public boolean addShip( int id, int shipid, int forceside ) { 
    229830                throw new RuntimeException("STUB"); 
    230831        } 
     
    232833        //--------------------------------------------------------------------- 
    233834        // 
    234         // addShip - Ein Schiff oder eine Flotte zu der Schlacht hinzufuegen 
     835        // load - Die Schlacht laden 
    235836        // 
    236837        //--------------------------------------------------------------------- 
    237838 
    238         public void addShip( int id, int shipid ) { 
    239                 addShip(id, shipid, -1); 
    240         } 
    241          
    242         public void addShip( int id, int shipid, int forceside ) { 
    243                 throw new RuntimeException("STUB"); 
    244         } 
    245          
    246         //--------------------------------------------------------------------- 
    247         // 
    248         // load - Die Schlacht laden 
    249         // 
    250         //--------------------------------------------------------------------- 
    251  
    252         public void load(int battleID, int id, int ownShipID, int enemyShipID, boolean forcejoin ) { 
    253                 throw new RuntimeException("STUB"); 
    254         } 
    255          
    256         //------------------------------------------------------------------------------- 
    257         // 
    258         // logme - Nachricht an den aktuellen Spieler ausgeben (bzw ausgabe vorbereiten) 
    259         // 
    260         //------------------------------------------------------------------------------- 
    261  
     839        public boolean load(int battleID, int id, int ownShipID, int enemyShipID, int forcejoin ) { 
     840                Context context = ContextMap.getContext(); 
     841                Database db = context.getDatabase(); 
     842                 
     843                /* 
     844                        TODO: 
     845                                - Update der Allys falls der Commander einer Seite einer Ally beitritt (und vorher in keiner war) 
     846                                - Update der Schiffe, falls ein Spieler nicht mehr einer der beiden Seiten angehoert (und ggf auch update der Kommandanten) 
     847                */ 
     848                SQLResultRow battledata = db.first( "SELECT * FROM battles WHERE id=",battleID); 
     849         
     850                if( battledata.isEmpty() ) { 
     851                        db.update("UPDATE ships SET battle=0 WHERE id>0 AND battle=",battleID); 
     852                        context.addError("Die Schlacht ist bereits zuende!"); 
     853                        return false; 
     854                } 
     855         
     856                this.id = battleID; 
     857                this.points[0] = battledata.getInt("com1Points"); 
     858                this.points[1] = battledata.getInt("com2Points"); 
     859                this.ally[0] = battledata.getInt("ally1"); 
     860                this.ally[1] = battledata.getInt("ally2"); 
     861                this.commander[0] = battledata.getInt("commander1"); 
     862                this.commander[1] = battledata.getInt("commander2"); 
     863                this.x = battledata.getInt("x"); 
     864                this.y = battledata.getInt("y"); 
     865                this.system = battledata.getInt("system"); 
     866                this.ready[0] = battledata.getBoolean("ready1"); 
     867                this.ready[1] = battledata.getBoolean("ready2"); 
     868                this.comMsg[0] = battledata.getString("com1Msg"); 
     869                this.comMsg[1] = battledata.getString("com2Msg"); 
     870                this.betak[0] = battledata.getBoolean("com1BETAK"); 
     871                this.betak[1] = battledata.getBoolean("com2BETAK"); 
     872                this.takeCommand[0] = battledata.getInt("takeCommand1"); 
     873                this.takeCommand[1] = battledata.getInt("takeCommand2"); 
     874                this.blockcount = battledata.getInt("blockcount"); 
     875                this.lastturn = battledata.getInt("lastturn"); 
     876                this.visibility = battledata.getString("visibility"); 
     877                this.quest = battledata.getInt("quest"); 
     878                this.guest = false; 
     879                this.flags = battledata.getInt("flags"); 
     880                 
     881                this.addCommanders.add(0, new ArrayList<Integer>()); 
     882                this.addCommanders.add(1, new ArrayList<Integer>()); 
     883         
     884                this.tableBuffer = battledata; 
     885         
     886                User auser = context.createUserObject(id); 
     887                 
     888                // 
     889                // Weitere Commander in Folge von Questschlachten feststellen 
     890                // 
     891                if( (this.quest != 0) && !Common.inArray(id,this.commander) && ((this.commander[0] < 0) ^ (this.commander[1] < 0) ) ) { 
     892                        if( auser.hasFlag(User.FLAG_QUEST_BATTLES) || auser.getAccessLevel() > 20 ) { 
     893                                if( this.commander[0] < 0 )  { 
     894                                        this.addCommanders.get(0).add(id); 
     895                                } 
     896                                else {