Changeset 4f1973c


Ignore:
Timestamp:
May 23, 2010, 3:55:14 PM (10 years ago)
Author:
Michael Seifert <mseifert@…>
Branches:
master
Children:
7ec5446
Parents:
5a3c8d9
Message:

Support of sc2replay files of version 2 seems stable;

Changed the SC2ActionFilter

Location:
src/main
Files:
6 added
9 edited

Legend:

Unmodified
Added
Removed
  • src/main/java/de/erichseifert/warp/DefaultReplay.java

    r5a3c8d9 r4f1973c  
    3232 * allow support for specific replay versions.
    3333 */
    34 public class DefaultReplay extends DefaultVersionedComponent    implements Replay {
     34public class DefaultReplay extends DefaultVersionedComponent implements Replay {
    3535        private final List<Player> players;
    3636        private final File file;
  • src/main/java/de/erichseifert/warp/gui/DefaultPlayerRenderer.java

    r5a3c8d9 r4f1973c  
    5050
    5151import de.erichseifert.warp.Player;
     52import de.erichseifert.warp.util.GUIUtil;
    5253
    5354public class DefaultPlayerRenderer<T extends Player> implements ItemRenderer<T> {
     
    7879
    7980                        playerLabel = new JLabel();
     81                        playerLabel.setToolTipText(GUIUtil.toHTMLColor(player.getColor()));
    8082                        playerLabel.addMouseListener(new MouseAdapter() {
    8183                                @Override
  • src/main/java/de/erichseifert/warp/gui/ReplayCellEditor.java

    r5a3c8d9 r4f1973c  
    2424import java.awt.Component;
    2525import java.io.File;
    26 import java.io.IOException;
    2726
    2827import javax.swing.DefaultCellEditor;
     
    3130
    3231import de.erichseifert.warp.Replay;
    33 import de.erichseifert.warp.replays.sc2replay.SC2Replay;
     32import de.erichseifert.warp.replays.ReplayParserFactory;
    3433import de.erichseifert.warp.util.FileUtil;
    3534
     
    101100
    102101                // Assure re-insertion of the renamed replay
    103                 try {
    104                         this.replay = new SC2Replay(replayFileNew);
    105                 } catch (IOException e) {
    106                         // TODO Auto-generated catch block
    107                         e.printStackTrace();
    108                 }
     102                this.replay = ReplayParserFactory.getInstance().getReplayParser(replayFileNew);
    109103
    110104                // Remove an empty directory, if there are no files left
  • src/main/java/de/erichseifert/warp/gui/ReplayParserGUI.java

    r5a3c8d9 r4f1973c  
    282282                // Refresh replay table
    283283                replayTableModel.setRowCount(0);
    284                 Collection<File> replayFiles = walk(replayDir, 2);
     284                Collection<File> replayFiles = walk(replayDir, 3);
    285285                for (File replayFile : replayFiles) {
    286286                        Replay replay = replayFactory.getReplayParser(replayFile);
  • src/main/java/de/erichseifert/warp/replays/ReplayParserFactory.java

    r5a3c8d9 r4f1973c  
    8787                                Constructor<? extends Replay> constructor = clazz.getConstructor(File.class);
    8888                                parser = constructor.newInstance(file);
     89                                break;
    8990                        } catch (SecurityException e) {
    9091                                // TODO Auto-generated catch block
    9192                                e.printStackTrace();
    92                                 continue;
    9393                        } catch (NoSuchMethodException e) {
    9494                                // TODO Auto-generated catch block
    9595                                e.printStackTrace();
    96                                 continue;
    97                         } catch (IllegalArgumentException e) {
    98                                 // TODO Auto-generated catch block
    99                                 e.printStackTrace();
    100                                 continue;
    10196                        } catch (InstantiationException e) {
    10297                                // TODO Auto-generated catch block
    10398                                e.printStackTrace();
    104                                 continue;
    10599                        } catch (IllegalAccessException e) {
    106100                                // TODO Auto-generated catch block
    107101                                e.printStackTrace();
    108                                 continue;
    109102                        } catch (InvocationTargetException e) {
    110103                                // TODO Auto-generated catch block
    111                                 e.printStackTrace();
    112                                 continue;
     104                                System.err.println(e.getTargetException());
    113105                        }
    114106                }
  • src/main/java/de/erichseifert/warp/replays/sc2replay/SC2Replay.java

    r5a3c8d9 r4f1973c  
    2222package de.erichseifert.warp.replays.sc2replay;
    2323
    24 import java.io.File;
    25 import java.io.IOException;
    26 import java.io.RandomAccessFile;
    27 import java.nio.ByteBuffer;
    28 import java.nio.ByteOrder;
    29 import java.nio.channels.FileChannel;
    30 import java.nio.channels.FileChannel.MapMode;
    31 import java.util.HashMap;
    32 import java.util.LinkedList;
    33 import java.util.List;
    34 import java.util.Map;
    35 
    3624import javax.swing.ImageIcon;
    3725
    38 import de.erichseifert.mpqparser.MPQArchive;
    39 import de.erichseifert.warp.ChatMessage;
    40 import de.erichseifert.warp.DefaultChatMessage;
    41 import de.erichseifert.warp.DefaultReplay;
    42 import de.erichseifert.warp.GameAction;
    43 import de.erichseifert.warp.GameActionFactory;
    44 import de.erichseifert.warp.Player;
    45 import de.erichseifert.warp.replays.sc2replay.actions.SC2Action;
    46 import de.erichseifert.warp.replays.sc2replay.actions.SC2ActionFactory;
    47 import de.erichseifert.warp.replays.sc2replay.util.SC2ReplayUtil;
    48 import de.erichseifert.warp.util.ReplayUtil;
     26import de.erichseifert.warp.Replay;
    4927
    50 /**
    51  * Class that represents a SC2Replay file.
    52  * This class parses the contents of the latter.
    53  */
    54 public class SC2Replay extends DefaultReplay {
    55         static {
    56                 //addVersionSupport(SC2Replay.class, "0.2.0.13891");
    57         }
     28public interface SC2Replay extends Replay {
    5829
    59         private static final int REPLAY_DATA_OFFSET = 1024;
    60         private static final int FILE_INDEX_META_DATA = 0;
    61         private static final int FILE_INDEX_MAP_PREVIEW = 1;
    62         private static final int FILE_INDEX_ACTIONS = 2;
    63         private static final int FILE_INDEX_CHAT_LOG = 3;
    64 
    65         private static final byte CHANNEL_CODE_ALL = 0x0;
    66         private static final byte CHANNEL_CODE_TEAM = 0x2;
    67         private static final byte CHANNEL_CODE_BLINK = (byte) 0x83;
    68         private static final byte CHANNEL_FLAG_MESSAGE_SIZE = 0x8;
    69 
    70         private ImageIcon mapPreview;
    71 
    72         /**
    73          * Creates a new <code>Starcraft2Replay</code> object by parsing the specified file.
    74          * @param file
    75          * @throws IOException
    76          */
    77         public SC2Replay(File file) throws IOException {
    78                 super(file);
    79                 FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel();
    80                 ByteBuffer src = fileChannel.map(MapMode.READ_ONLY, 0, REPLAY_DATA_OFFSET);
    81                 src.order(ByteOrder.BIG_ENDIAN);
    82 
    83                 // Read uncompressed replay information
    84                 src.position(src.position()+39);
    85                 String version = src.get()+"."+src.get()+"."+src.get()+"."+src.getInt();
    86                 setVersion(version);
    87                 if (!isVersionSupported(getClass(), version)) {
    88                         throw new IllegalArgumentException("Unsupported version: "+version);
    89                 }
    90                 src.position(src.position()+6);
    91                 setDuration(src.getShort());
    92 
    93                 System.out.println("Parsing file: "+file.getPath()+" Version: "+version);
    94                 // Read MPQ archive
    95                 MPQArchive archive = new MPQArchive(file, REPLAY_DATA_OFFSET);
    96                 /*
    97                  * NOTE: In order to create/read the players, we have to parse the chat log and the actions first.
    98                  */
    99                 // Read actions
    100                 ByteBuffer actionBytes = ByteBuffer.wrap(archive.getFiles()[FILE_INDEX_ACTIONS].getBytes());
    101                 Map<Integer, List<GameAction>> actions = new HashMap<Integer, List<GameAction>>();
    102                 GameActionFactory<SC2Action> actionFactory = SC2ActionFactory.getInstance(this);
    103                 while (actionBytes.hasRemaining()) {
    104                         SC2Action action = actionFactory.getAction(actionBytes);
    105                         int playerIndex = action.getPlayerIndex();
    106                         List<GameAction> actionList = actions.get(playerIndex);
    107                         if (actionList == null) {
    108                                 actionList = new LinkedList<GameAction>();
    109                                 actions.put(playerIndex, actionList);
    110                         }
    111                         actionList.add(action);
    112                 }
    113 
    114                 // Read chat log
    115                 Map<Integer, List<ChatMessage>> messages = new HashMap<Integer, List<ChatMessage>>();
    116                 if (archive.getFiles()[FILE_INDEX_CHAT_LOG] != null) {
    117                         ByteBuffer chatBuffer = ByteBuffer.wrap(archive.getFiles()[FILE_INDEX_CHAT_LOG].getBytes());
    118                         chatBuffer.order(ByteOrder.LITTLE_ENDIAN);
    119                         // Skip unknown 7 byte blocks
    120                         try {
    121                                 while (ReplayUtil.lookAhead(chatBuffer, 2) == (byte) 0x80) {
    122                                         chatBuffer.position(chatBuffer.position()+7);
    123                                 }
    124                         }
    125                         catch (IndexOutOfBoundsException e) {
    126                                 // Chat log empty, only header present
    127                                 //System.err.println("And error occured when parsing the chat log. file="+file.getPath());
    128                         }
    129                         // Read messages
    130                         int timeStamp = 0;
    131                         while (chatBuffer.hasRemaining()) {
    132                                 // Read time offset
    133                                 int timeOffset = SC2ReplayUtil.getTimeOffset(chatBuffer);
    134                                 timeStamp += timeOffset;
    135 
    136                                 byte playerIndex = chatBuffer.get();
    137                                 byte channelCode = chatBuffer.get();
    138                                 int channel;
    139                                 if (channelCode == CHANNEL_CODE_BLINK) {
    140                                         // TODO Read blink
    141                                         // 4 bytes x coord
    142                                         chatBuffer.position(chatBuffer.position() + 4);
    143                                         // 4 bytes y coord
    144                                         chatBuffer.position(chatBuffer.position() + 4);
    145                                         continue;
    146                                 }
    147                                 else if (channelCode == CHANNEL_CODE_ALL) {
    148                                         channel = ChatMessage.ALL;
    149                                 }
    150                                 else if (channelCode == CHANNEL_CODE_TEAM) {
    151                                         channel = ChatMessage.TEAM;
    152                                 }
    153                                 else {
    154                                         channel = channelCode;
    155                                         System.err.println("Unknown channel code: "+channelCode);
    156                                 }
    157                                 int messageLength = (short) chatBuffer.get() & 0xFF;
    158                                 // If the flag in the channel byte, which modifies the message length is set
    159                                 if ((channelCode & CHANNEL_FLAG_MESSAGE_SIZE) != 0) {
    160                                         messageLength += 64;
    161                                 }
    162                                 String messageString = ReplayUtil.getString(chatBuffer, messageLength);
    163                                 ChatMessage message = new DefaultChatMessage(timeStamp, channel, messageString);
    164                                 List<ChatMessage> messageList = messages.get(playerIndex-1);
    165                                 if (messageList == null) {
    166                                         messageList = new LinkedList<ChatMessage>();
    167                                         messages.put(playerIndex-1, messageList);
    168                                 }
    169                                 messageList.add(message);
    170                         }
    171                 }
    172 
    173                 // Read meta data
    174                 ReplayMetaData metaData = new ReplayMetaData(archive.getFiles()[FILE_INDEX_META_DATA].getBytes(), actions, messages);
    175                 List<? extends Player> playerList = metaData.getPlayers();
    176                 setPlayers(playerList);
    177 
    178                 // Extract map preview
    179                 mapPreview = new ImageIcon(archive.getFiles()[FILE_INDEX_MAP_PREVIEW].getBytes());
    180                 fileChannel.close();
    181         }
    182 
    183         /**
    184          * Returns the map preview of the replay.
    185          * @return Map preview.
    186          */
    187         public ImageIcon getMapPreview() {
    188                 return mapPreview;
    189         }
    190 
    191         @Override
    192         public boolean equals(Object obj) {
    193                 if (obj != null && obj instanceof SC2Replay) {
    194                         SC2Replay replayObj = (SC2Replay) obj;
    195                         return getFile().getPath().equals(replayObj.getFile());
    196                 }
    197                 return super.equals(obj);
    198         }
     30        ImageIcon getMapPreview();
    19931}
  • src/main/java/de/erichseifert/warp/replays/sc2replay/actions/SC2ActionFactory.java

    r5a3c8d9 r4f1973c  
    3838        private static final byte CODE_GROUPX = 0x0D;
    3939        private static final byte CODE_GROUP_UPDATED = 0x0C;
    40         private static final byte CODE_ENTER_GAME = 0x1B;
     40        private static final byte CODE_ENTER_GAME = 0x0B;
    4141        private static final byte CODE_MOVE_SCREEN = (byte) 0x81;
    4242        private static final byte CODE_UNKNOWN3 = (byte) 0x89;
     
    6868                // Read action
    6969                byte code = src.get();
    70                 if (code == CODE_ORDER) {
     70                if (code == CODE_ORDER && eventTypeCode == 1) {
    7171                        action = new Order(timeStamp, eventTypeCode, globalEvent, playerIndex, src);
    7272                        //System.out.println("Order action: offset="+pos+", length="+(src.position()-pos)+" bytes");
     
    113113                        //System.out.println("Sync action: offset="+pos+", length="+(src.position()-pos)+" bytes");
    114114                }
    115                 else if (code == CODE_ENTER_GAME) {
     115                else if ((code & 0xF) == CODE_ENTER_GAME && eventTypeCode == 0) {
    116116                        action = new EnterGame(timeStamp, eventTypeCode, globalEvent, playerIndex);
    117117                }
  • src/main/java/de/erichseifert/warp/replays/sc2replay/actions/SC2ActionFilter.java

    r5a3c8d9 r4f1973c  
    2424import de.erichseifert.warp.ActionFilter;
    2525import de.erichseifert.warp.GameAction;
    26 import de.erichseifert.warp.replays.sc2replay.actions.Order.OrderCode;
    2726
    2827public class SC2ActionFilter implements ActionFilter {
     
    4342                }
    4443                else if (action instanceof Order) {
    45                         OrderCode code = ((Order) action).getOrderCode();
    46                         // A click ID indicates a right click -> one action
    47                         if (code == Order.ID_CLICK) {
    48                                 return 1;
    49                         }
    50                         // Otherwise an ability has to be selected first -> two actions
    51                         return 2;
     44                        return 1;
    5245                }
    5346                else if (action instanceof StartGame) {
     
    5548                }
    5649                else if (action instanceof Group) {
    57                         if (((Group) action).isAssigned()) {
    58                                 return 2;
    59                         }
    6050                        return 1;
    6151                }
    6252                else if (action instanceof SendResources) {
    6353                        // FIXME Dependent on the amount of resources sent
     54                        return 3;
    6455                }
    6556                else if (action instanceof Unknown || action instanceof Unknown2 || action instanceof Unknown3) {
  • src/main/resources/replayparsers.txt

    r5a3c8d9 r4f1973c  
    1 sc2replay de.erichseifert.warp.replays.sc2replay.SC2Replay
     1sc2replay de.erichseifert.warp.replays.sc2replay.SC2Replay_v1
     2sc2replay de.erichseifert.warp.replays.sc2replay.SC2Replay_v2
Note: See TracChangeset for help on using the changeset viewer.