├── .gitignore
├── hl2parse-binary
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── technofovea
│ └── hl2parse
│ ├── OffsetBuffer.java
│ ├── ParseUtil.java
│ ├── Vector3f.java
│ ├── bsp
│ ├── BinaryBspAnalyzer.java
│ ├── BspLumpHeader.java
│ ├── BspParseException.java
│ ├── GameLumpHeader.java
│ ├── GamePropSection.java
│ ├── SourceMapAnalyzer.java
│ └── package.html
│ ├── mdl
│ ├── ModelData.java
│ ├── ModelFlag.java
│ ├── ModelParseException.java
│ ├── ModelSection.java
│ ├── PhyData.java
│ ├── PhyParseException.java
│ └── package.html
│ └── registry
│ ├── BlobDword.java
│ ├── BlobFolder.java
│ ├── BlobNode.java
│ ├── BlobParseFailure.java
│ ├── BlobRaw.java
│ ├── BlobText.java
│ ├── BlobValue.java
│ ├── CdrParser.java
│ ├── CellCollection.java
│ ├── CellItem.java
│ ├── ClientRegistry.java
│ ├── RegParser.java
│ └── package.html
├── hl2parse-common
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── technofovea
│ │ │ └── hl2parse
│ │ │ ├── JxPathUtil.java
│ │ │ ├── entdata
│ │ │ ├── DefaultPathFixer.java
│ │ │ ├── DependencyFinder.java
│ │ │ ├── EntdataException.java
│ │ │ ├── MapEntity.java
│ │ │ ├── PathFixer.java
│ │ │ ├── ValueSource.java
│ │ │ └── package.html
│ │ │ ├── fgd
│ │ │ ├── ChoicesValue.java
│ │ │ ├── FgdEntClass.java
│ │ │ ├── FgdInput.java
│ │ │ ├── FgdOutput.java
│ │ │ ├── FgdProperty.java
│ │ │ ├── FgdSpec.java
│ │ │ ├── FlagValue.java
│ │ │ ├── VisGroup.java
│ │ │ └── package.html
│ │ │ ├── vdf
│ │ │ ├── GameConfigReader.java
│ │ │ ├── GameInfoReader.java
│ │ │ ├── MaterialReader.java
│ │ │ ├── ParticleManifestReader.java
│ │ │ ├── PropDataReader.java
│ │ │ ├── SoundScapeReader.java
│ │ │ ├── SteamMetaReader.java
│ │ │ ├── VdfAttribute.java
│ │ │ ├── VdfNode.java
│ │ │ ├── VdfRoot.java
│ │ │ └── package.html
│ │ │ └── xml
│ │ │ ├── MaterialRefList.java
│ │ │ └── MaterialReference.java
│ └── resources
│ │ └── com
│ │ └── technofovea
│ │ └── hl2parse
│ │ └── vdf
│ │ └── DefaultMaterials.xml
│ └── test
│ └── resources
│ └── log4j.xml
├── hl2parse-parsers
├── pom.xml
└── src
│ └── main
│ ├── antlr3
│ └── com
│ │ └── technofovea
│ │ └── hl2parse
│ │ ├── fgd
│ │ └── ForgeGameData.g
│ │ └── vdf
│ │ ├── SloppyParser.g
│ │ └── ValveTokenLexer.g
│ └── java
│ └── com
│ └── technofovea
│ └── hl2parse
│ ├── ParserException.java
│ └── fgd
│ ├── DefaultLoader.java
│ └── FgdLoader.java
├── hl2parse-tests
├── pom.xml
└── src
│ └── test
│ ├── java
│ └── com
│ │ └── technofovea
│ │ └── hl2parse
│ │ ├── bsp
│ │ └── BspParseTest.java
│ │ ├── entdata
│ │ └── EntityProcessingTest.java
│ │ ├── fgd
│ │ ├── BaselineTest.java
│ │ └── CombinationTest.java
│ │ ├── mdl
│ │ └── ModelDataTest.java
│ │ ├── registry
│ │ └── ClientRegistryTest.java
│ │ ├── vdf
│ │ └── ParseTest.java
│ │ └── xml
│ │ └── XmlTest.java
│ └── resources
│ ├── com
│ └── technofovea
│ │ └── hl2parse
│ │ ├── bsp
│ │ ├── test_bsp_parse.bsp
│ │ ├── test_bsp_parse.log
│ │ ├── test_bsp_parse.vmf
│ │ └── test_bsp_parse.vmx
│ │ ├── entdata
│ │ ├── base.fgd
│ │ ├── ctf_2fort.ent
│ │ └── tf.fgd
│ │ ├── fgd
│ │ ├── cyclic1.fgd
│ │ ├── cyclic2.fgd
│ │ ├── imported1.fgd
│ │ ├── imported2.fgd
│ │ ├── importer.fgd
│ │ ├── inherit_test.fgd
│ │ └── overall.fgd
│ │ ├── mdl
│ │ ├── buoy_ref.mdl
│ │ └── buoy_ref.phy
│ │ ├── utest.bsp
│ │ └── vdf
│ │ ├── Cloud001c.vmt
│ │ ├── GameConfig.txt
│ │ ├── SteamAppData.vdf
│ │ ├── ammo_red_bg.vmt
│ │ ├── blendcobbletocobblesnow001.vmt
│ │ ├── blue001.vmt
│ │ ├── brickwall001.vmt
│ │ ├── bubble.vmt
│ │ ├── computerwall005.vmt
│ │ ├── cp_dustbowl.ent
│ │ ├── detailsprites_2fort.vmt
│ │ ├── dirtroad001.vmt
│ │ ├── dispenser.vmt
│ │ ├── dota_english.txt
│ │ ├── glasswindow001a.vmt
│ │ ├── particle_rockettrail1.vmt
│ │ ├── particles_manifest.txt
│ │ ├── pl_goldrush.ent
│ │ ├── scorch1.vmt
│ │ ├── soundscapes_2fort.txt
│ │ ├── tf2_gameinfo.txt
│ │ ├── toolstrigger.vmt
│ │ ├── utest.ent
│ │ ├── water_2fort.vmt
│ │ └── water_2fort_beneath.vmt
│ └── log4j.xml
├── license_header.txt
├── pom.xml
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | hl2parse-*/target/**
2 | hl2parse-*/apidocs/**
3 |
--------------------------------------------------------------------------------
/hl2parse-binary/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | com.technofovea
7 | hl2parse
8 | 1.2.2-SNAPSHOT
9 |
10 |
11 | hl2parse-binary
12 | hl2parse-binary
13 |
14 |
15 |
16 |
17 |
18 |
19 | com.technofovea
20 | hl2parse-common
21 | compile
22 |
23 |
24 |
25 | junit
26 | junit
27 | test
28 |
29 |
30 |
31 | org.slf4j
32 | slf4j-api
33 |
34 |
35 |
36 | org.slf4j
37 | slf4j-log4j12
38 |
39 |
40 |
41 |
42 | ${basedir}/..
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/OffsetBuffer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse;
14 |
15 | import java.nio.ByteBuffer;
16 | import java.nio.ByteOrder;
17 |
18 |
19 | /**
20 | * This class manages a buffer which is a slice from a parent buffer. The main
21 | * benefit is that it remembers its own offset, which is useful for debugging.
22 | *
23 | * Note that this class sets the resulting child buffers to little-endian.
24 | * @author Darien Hager
25 | */
26 | public class OffsetBuffer {
27 |
28 | /**
29 | * The parent buffer
30 | */
31 | protected ByteBuffer parent;
32 | /**
33 | * The offset in the parent at which the child buffer begins
34 | */
35 | protected int parentOffset;
36 | /**
37 | * The created child buffer which is a view of the parent
38 | */
39 | protected ByteBuffer buf;
40 |
41 |
42 | /**
43 | * Creates and manages a new sliced "view" of a buffer.
44 | *
45 | * @param parent The parent buffer to create a sliced view of.
46 | * @param parentOffset The offset at which to start the slice
47 | * @param len The length of the slice
48 | */
49 | public OffsetBuffer(ByteBuffer parent, int parentOffset, int len) {
50 | this.parent = parent;
51 | this.parentOffset = parentOffset;
52 |
53 | int pos = parent.position();
54 | int lim = parent.limit();
55 |
56 | parent.position(parentOffset);
57 | parent.limit(parentOffset+len);
58 | this.buf = parent.slice();
59 | parent.position(pos);
60 | parent.limit(lim);
61 |
62 | this.buf.order(ByteOrder.LITTLE_ENDIAN);
63 |
64 | }
65 |
66 |
67 |
68 | /**
69 | * Get the child-buffer being managed by this object. This buffer
70 | * will generally be in little-endian mode.
71 | * @return A buffer which is a view of the parent
72 | */
73 | public ByteBuffer getBuf() {
74 | return buf;
75 | }
76 |
77 | /**
78 | * Gets the original parent buffer
79 | * @return The parent buffer
80 | */
81 | public ByteBuffer getParent() {
82 | return parent;
83 | }
84 |
85 | /**
86 | * Retrieves the offset in the parent buffer at which the child buffer begins.
87 | * @return A position within the parent buffer
88 | */
89 | public int getParentOffset() {
90 | return parentOffset;
91 | }
92 | /**
93 | * Retrieves the position in the parent buffer which corresponds to
94 | * the current position of the child buffer, taking the offset into account.
95 | * @return A position in the parent buffer
96 | */
97 | public int getAbsolutePosition(){
98 | return parentOffset + buf.position();
99 | }
100 |
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/ParseUtil.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse;
14 |
15 |
16 |
17 | import java.io.File;
18 | import java.io.FileInputStream;
19 | import java.io.IOException;
20 | import java.nio.ByteBuffer;
21 | import java.nio.ByteOrder;
22 | import java.nio.MappedByteBuffer;
23 | import java.nio.channels.FileChannel;
24 | import java.util.Arrays;
25 | import java.util.BitSet;
26 |
27 | /**
28 | * Miscellaneous utilities for parsing both binary and text-based files.
29 | * @author Darien Hager
30 | */
31 | public class ParseUtil {
32 |
33 | /**
34 | * The null byte terminator used in C-style strings
35 | */
36 | public static final int NULL_TERMINATOR = 0x00;
37 | static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
38 |
39 | /**
40 | * Given an integer value, reinterpret it as a string stored in four bytes.
41 | *
42 | * This is useful for a few places where developers have chosen integer IDs
43 | * which map to a human-readable mnemonic value.
44 | *
45 | * @param i The integer to interpret
46 | * @param reversed True for big-endian, false for little-endian
47 | * @return A string representation of the integer
48 | */
49 | public static String toAscii(int i, boolean reversed) {
50 | byte[] bytes = new byte[4];
51 | if (!reversed) {
52 | bytes[0] = (byte) (i >> 24);
53 | bytes[1] = (byte) ((i << 8) >> 24);
54 | bytes[2] = (byte) ((i << 16) >> 24);
55 | bytes[3] = (byte) ((i << 24) >> 24);
56 | } else {
57 | bytes[3] = (byte) (i >> 24);
58 | bytes[2] = (byte) ((i << 8) >> 24);
59 | bytes[1] = (byte) ((i << 16) >> 24);
60 | bytes[0] = (byte) ((i << 24) >> 24);
61 | }
62 | return new String(bytes);
63 | }
64 |
65 | /**
66 | * Given an array of bytes, return a string of hexadecimal characters.
67 | * @param bytes The byte array to interpret
68 | * @return A series of (upper-cased) hexadecimal characters, without any leading values such as 0x
69 | */
70 | public static String toHex(byte[] bytes) {
71 | StringBuilder sb = new StringBuilder();
72 | for (byte b : bytes) {
73 | sb.append(HEX_CHARS[(b & 0xF0) >>> 4]);
74 | sb.append(HEX_CHARS[b & 0x0F]);
75 | }
76 |
77 | return sb.toString();
78 | }
79 |
80 | public static String toHex(byte b){
81 | return toHex(new byte[]{b});
82 | }
83 |
84 | /**
85 | * Interprets the bytes inside the given buffer as a hexadecimal string.
86 | *
87 | * The data in the buffer between its position and limit will be used, and the position will
88 | * be restored to its original value afterwards.
89 | *
90 | * @param buf The buffer to interpret, using the data between its position and limit.
91 | * @return A string of (upper-cased) hexadecimal, with no leading prefix (ex. 0x)
92 | */
93 | public static String toHex(ByteBuffer buf) {
94 | int orig = buf.position();
95 | StringBuilder sb = new StringBuilder();
96 | while (buf.remaining() > 0) {
97 | byte b = buf.get();
98 | sb.append(HEX_CHARS[(b & 0xF0) >>> 4]);
99 | sb.append(HEX_CHARS[b & 0x0F]);
100 | }
101 |
102 | buf.position(orig);
103 | return sb.toString();
104 | }
105 |
106 | /**
107 | * Reads a null-terminated string from the current position of the given bytebuffer.
108 | * @param bb ByteBuffer to read from
109 | * @param limit The maximum number of characters to read before giving up.
110 | * @return The ASCII string that was found
111 | */
112 | public static String readString(ByteBuffer bb, int limit) {
113 | int max = Math.min(limit, bb.remaining());
114 | byte[] name = new byte[max];
115 | bb.get(name);
116 | return readString(name, max);
117 | }
118 |
119 | /**
120 | * Reads a null-terminated string from the current position of the given byte array.
121 | * @param buf ByteBuffer to read from
122 | * @param limit The maximum number of characters to read before giving up.
123 | * @return The ASCII string that was found
124 | */
125 | public static String readString(byte[] buf, int limit) {
126 | int max = Math.min(limit, buf.length);
127 | int firstnull = max;
128 | for (int i = 0; i
129 | < buf.length; i++) {
130 | if (buf[i] == NULL_TERMINATOR) {
131 | firstnull = i;
132 | break;
133 |
134 | }
135 | }
136 | return new String(Arrays.copyOf(buf, firstnull));
137 | }
138 |
139 | /**
140 | * Maps the given file into memory and returns a representative buffer.
141 | * @param target The file to load
142 | * @return A read-only buffer of corresponding data in little-endian mode.
143 | * @throws IOException If an error occurred accessing or mapping the file.
144 | */
145 | public static MappedByteBuffer mapFile(File target) throws IOException {
146 | FileInputStream fos = new FileInputStream(target);
147 | FileChannel fc = fos.getChannel();
148 | MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, target.length());
149 | mbb.order(ByteOrder.LITTLE_ENDIAN);
150 | return mbb;
151 | }
152 |
153 | /**
154 | * Reads a series of bytes from the given buffer, turning them into a
155 | * little-endian bit-set. The ByteBuffer's position is advanced appropriately.
156 | *
157 | * Thus the three-byte series of 10000001,00001000,00000000 has set flags
158 | * at positions 0,7, and 11
159 | * @param bb ByteBuffer to read from
160 | * @param numbytes Number of bytes to read.
161 | * @return A new BitSet with the correct areas set/unset
162 | */
163 | public static BitSet readBitset(ByteBuffer bb, int numbytes) {
164 | byte[] barr = new byte[numbytes];
165 |
166 | bb.get(barr);
167 | BitSet ret = new BitSet(numbytes * 8);
168 |
169 | for (int i_byte = 0; i_byte < barr.length; i_byte++) {
170 | for (int i = 0; i < 8; i++) {
171 | int idx = i_byte*8 + i;
172 | boolean isSet = (barr[i_byte] & (1 << i) )>0;
173 | ret.set(idx,isSet);
174 | }
175 | }
176 | return ret;
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/Vector3f.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse;
14 |
15 | import java.nio.BufferUnderflowException;
16 | import java.nio.ByteBuffer;
17 | import java.nio.ByteOrder;
18 |
19 | /**
20 | * Utility class to represent 12-byte vectors
21 | * @author Darien Hager
22 | */
23 | public class Vector3f {
24 |
25 | static final int BYTELEN = 4;
26 | static final int NUMVALS = 3;
27 |
28 | float x;
29 | float y;
30 | float z;
31 |
32 | /**
33 | * Creates a new object, attempting to draw from data in the given buffer.
34 | * @param b The buffer that data will be read from. The buffer's position
35 | * value will be changed when the constructor completes.
36 | * @throws BufferUnderflowException If the buffer does not have enough data availible.
37 | */
38 | public Vector3f(ByteBuffer b) {
39 | super();
40 | byte[] backing = new byte[NUMVALS*BYTELEN];
41 | b.get(backing);
42 |
43 | ByteBuffer temp = ByteBuffer.wrap(backing);
44 | temp.order(ByteOrder.LITTLE_ENDIAN);
45 |
46 | x = temp.getFloat();
47 | y = temp.getFloat();
48 | z = temp.getFloat();
49 |
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return x + ", " + y + ", " + z;
55 | }
56 |
57 | public String toStringRounded() {
58 | return Math.round(x) + ", " + Math.round(y) + ", " + Math.round(z);
59 | }
60 |
61 | public byte[] toBytes() {
62 | byte[] backing = new byte[NUMVALS*BYTELEN];
63 | ByteBuffer b = ByteBuffer.wrap(backing);
64 | b.putFloat(x);
65 | b.putFloat(y);
66 | b.putFloat(z);
67 | return backing;
68 | }
69 |
70 | public float getX() {
71 | return x;
72 | }
73 |
74 | public float getY() {
75 | return y;
76 | }
77 |
78 | public float getZ() {
79 | return z;
80 | }
81 |
82 | public void setX(float x) {
83 | this.x = x;
84 | }
85 |
86 | public void setY(float y) {
87 | this.y = y;
88 | }
89 |
90 | public void setZ(float z) {
91 | this.z = z;
92 | }
93 |
94 |
95 |
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/bsp/BinaryBspAnalyzer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.bsp;
14 |
15 | import com.technofovea.hl2parse.OffsetBuffer;
16 | import com.technofovea.hl2parse.ParseUtil;
17 | import java.nio.BufferUnderflowException;
18 | import java.nio.ByteBuffer;
19 | import java.nio.ByteOrder;
20 | import java.util.Arrays;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 |
24 | /**
25 | * This class serves as a base for writing classes which interpret the venerable BSP map format.
26 | * @todo Refactor into factory methods
27 | * @author Darien Hager
28 | */
29 | public abstract class BinaryBspAnalyzer {
30 |
31 | private static final Logger logger = LoggerFactory.getLogger(BinaryBspAnalyzer.class);
32 | /**
33 | * The buffer (probably mapped) which represents the whole file data.
34 | * Should be read-only and little-endian.
35 | */
36 | protected ByteBuffer coreBuffer;
37 | /**
38 | * The version code found within the map
39 | */
40 | protected int version;
41 | /**
42 | * Header data for each of the BSP lumps
43 | */
44 | protected BspLumpHeader[] lumps;
45 |
46 | /**
47 | * Creates a new analyzer against the given bytebuffer.
48 | * @param bb The data to analyze, from the current position to the limit
49 | * @throws BspParseException If there were any errors parsing
50 | */
51 | public BinaryBspAnalyzer(ByteBuffer bb) throws BspParseException {
52 | logger.debug("Processing map data ({} bytes)", bb.remaining());
53 |
54 | coreBuffer = bb.asReadOnlyBuffer();
55 | coreBuffer.order(ByteOrder.LITTLE_ENDIAN);
56 |
57 | try {
58 | loadBasic();
59 | } catch (BufferUnderflowException bue) {
60 | throw new BspParseException(bue);
61 | }
62 | }
63 |
64 | private void loadBasic() throws BspParseException {
65 | final int num_lumps = getNumLumps();
66 | final byte[] expected_hdr = getInitialHeader();
67 | lumps = new BspLumpHeader[num_lumps];
68 | byte[] hdr = new byte[expected_hdr.length];
69 |
70 | coreBuffer.get(hdr);
71 | if (!Arrays.equals(hdr, expected_hdr)) {
72 | String hexHdr = ParseUtil.toHex(hdr);
73 | String hexExpected = ParseUtil.toHex(expected_hdr);
74 | throw new BspParseException("File does not begin with expected header. Expected "+hexExpected+" but got "+hexHdr);
75 | }
76 |
77 | int versionNumber = coreBuffer.getInt();
78 | logger.debug("Map version is {}", versionNumber);
79 | if (!handlesVersion(versionNumber)) {
80 | throw new BspParseException("Cannot handle file format version " + versionNumber);
81 | }
82 | version = versionNumber;
83 |
84 | for (int i = 0; i < getNumLumps(); i++) {
85 | logger.trace("Loading lump header #{}", i);
86 | lumps[i] = new BspLumpHeader(coreBuffer);
87 | }
88 |
89 |
90 |
91 | }
92 |
93 | /**
94 | * Get a buffer containing the payload data for the given lump.
95 | * @param lumpNum The lump to retrieve
96 | * @return The data, or null if the given lump does not exist
97 | */
98 | protected OffsetBuffer getLumpData(int lumpNum) {
99 | if (lumpNum < 0 || lumpNum >= lumps.length) {
100 | logger.error("BSP lump {} was out-of-range and could not be found", lumpNum);
101 | return null;
102 | }
103 | BspLumpHeader l = lumps[lumpNum];
104 |
105 | return new OffsetBuffer(coreBuffer, l.getOffset(), l.getLength());
106 | }
107 |
108 | /**
109 | * Checks whether a given BSP version is supported by this analyzer
110 | * @param version The version number to check
111 | * @return True if supported, false otherwise
112 | */
113 | protected abstract boolean handlesVersion(int version);
114 |
115 | /**
116 | * Get the number of lumps expected in this file
117 | * @return The number of lumps which are supported
118 | */
119 | protected abstract int getNumLumps();
120 |
121 | /**
122 | * Get the expected header for the file
123 | * @return The bytes expected
124 | */
125 | protected abstract byte[] getInitialHeader();
126 | }
127 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/bsp/BspLumpHeader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.bsp;
14 |
15 | import java.nio.ByteBuffer;
16 |
17 | /**
18 | * Stores header information for a BSP lump
19 | * @author Darien Hager
20 | */
21 | public class BspLumpHeader {
22 |
23 | //TODO handle the reordering in Version 21 L4d
24 | /**
25 | * The length of the lump identifier bytes
26 | */
27 | protected static int IDENT_LEN = 4;
28 | /**
29 | * The offset of the game lump within the data
30 | */
31 | protected int offset;
32 | /**
33 | * The length of the game lump
34 | */
35 | protected int length;
36 | /**
37 | * The version number for the game lump
38 | */
39 | protected int version;
40 | /**
41 | * The identity code given to this lump
42 | */
43 | protected byte[] identCode = new byte[IDENT_LEN];
44 |
45 | /**
46 | * Creates a new BspLumpHeader, drawing from the given buffer
47 | * @param lumpData The buffer to be read from. On success, the buffer's position will have been advanced.
48 | * @throws BspParseException If the lump header is invalid.
49 | */
50 | public BspLumpHeader(ByteBuffer lumpData) throws BspParseException {
51 | final int originalPosition = lumpData.position();
52 | boolean resetPosition = true;
53 |
54 | try {
55 | offset = lumpData.getInt();
56 | length = lumpData.getInt();
57 | version = lumpData.getInt();
58 | lumpData.get(identCode);
59 |
60 | if (offset < 0) {
61 | throw new BspParseException("Lump header has negative offset");
62 | }
63 | if (length < 0) {
64 | throw new BspParseException("Lump header has negative length");
65 | }
66 | resetPosition = false; // Success, no need to reset
67 |
68 | } finally {
69 | if (resetPosition) {
70 | lumpData.position(originalPosition);
71 | }
72 | }
73 | }
74 |
75 | /**
76 | * Retrieves the lump identifier bytes
77 | * @return A series of bytes of length {@link #IDENT_LEN}
78 | */
79 | public byte[] getIdentCode() {
80 | return identCode;
81 | }
82 |
83 | /**
84 | * Get the length of the data this header refers to
85 | * @return The data length in bytes
86 | */
87 | public int getLength() {
88 | return length;
89 | }
90 |
91 | /**
92 | * Get the offset of the data this header refers to, relative
93 | * to the start of the BSP file
94 | * @return The offset at which this lump's data begins
95 | */
96 | public int getOffset() {
97 | return offset;
98 | }
99 |
100 | /**
101 | * Get the version number associated with this lump
102 | * @return A version number
103 | */
104 | public int getVersion() {
105 | return version;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/bsp/BspParseException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.bsp;
14 |
15 | /**
16 | * Thrown to indicate that a problem has occurred while parsing the binary data
17 | * of a BSP file or subsections within it.
18 | *
19 | * @author Darien Hager
20 | */
21 | public class BspParseException extends Exception {
22 |
23 | public BspParseException(Throwable cause) {
24 | super(cause);
25 | }
26 |
27 | public BspParseException(String message, Throwable cause) {
28 | super(message, cause);
29 | }
30 |
31 | public BspParseException(String message) {
32 | super(message);
33 | }
34 |
35 | public BspParseException() {
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/bsp/GameLumpHeader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.bsp;
14 |
15 | import com.technofovea.hl2parse.ParseUtil;
16 | import java.nio.ByteBuffer;
17 | import java.util.Arrays;
18 | import org.slf4j.Logger;
19 | import org.slf4j.LoggerFactory;
20 |
21 | /**
22 | * Holds metadata about a "game lump", not to be confused with a {@link BspLumpHeader},
23 | * game lumps are one more level of abstraction and are found within a BSP lump.
24 | *
25 | * @author Darien Hager
26 | */
27 | public class GameLumpHeader {
28 |
29 | private static final Logger logger = LoggerFactory.getLogger(GameLumpHeader.class);
30 | private int offset;
31 | private int length;
32 | private short version;
33 | private short flags;
34 | private final int id;
35 |
36 | /**
37 | * Attempts to create a new object from header data in the given bytebuffer.
38 | * @param lumpSection The buffer to be read from. On success, the buffer's position will have been advanced.
39 | * @throws BspParseException If an error occurred while processing.
40 | */
41 | public GameLumpHeader(ByteBuffer lumpSection) throws BspParseException {
42 | final int originalPosition = lumpSection.position();
43 | boolean resetPosition = true;
44 | try {
45 | id = lumpSection.getInt();
46 | flags = lumpSection.getShort();
47 | version = lumpSection.getShort();
48 | offset = lumpSection.getInt();
49 | length = lumpSection.getInt();
50 |
51 | if (offset < 0) {
52 | throw new BspParseException("Game lump header has negative offset");
53 | }
54 | if (length < 0) {
55 | throw new BspParseException("Game lump header has negative length");
56 | }
57 |
58 | if (logger.isDebugEnabled()) {
59 | String hexName = ParseUtil.toAscii(id, true);
60 | logger.debug("Game-lump created. ID {} ({}), version {}, offset {}, length {}", new Object[]{id, hexName, version, offset, length});
61 | }
62 | resetPosition = false; // Success, no need to reset
63 | } finally {
64 | if (resetPosition) {
65 | lumpSection.position(originalPosition);
66 | }
67 | }
68 | }
69 |
70 | /**
71 | * Turns a "nice" 4-character string name for a game lump into a game lump ID.
72 | * The ID is little-endian, meaning "prps" is reversed before becoming "1936749168"
73 | * @param str String to convert, should be 4 characters or less.
74 | * @return The integer value, or -1 on error
75 | */
76 | public static int stringToId(String str) {
77 | if (str.length() > 4) {
78 | logger.error("Game-lump 'hex label' was greater than four digits: " + str);
79 | return -1;
80 | }
81 | StringBuilder sb = new StringBuilder(str);
82 | sb.reverse();
83 | byte[] bytes = sb.toString().getBytes();
84 | if (bytes.length < 4) {
85 | //TODO verify that it adds zero to the correct end of the byte array
86 | bytes = Arrays.copyOf(bytes, 4);
87 | }
88 | ByteBuffer temp = ByteBuffer.wrap(bytes);
89 | return temp.getInt();
90 |
91 | }
92 |
93 | /**
94 | * Get the length of the data this header refers to
95 | * @return The data length in bytes
96 | */
97 | public int getLength() {
98 | return length;
99 | }
100 |
101 | /**
102 | * Get the offset within the game-lump of the data this refers to
103 | * @return The offset in bytes
104 | */
105 | public int getOffset() {
106 | return offset;
107 | }
108 |
109 | /**
110 | * Get the version of the game-lump
111 | * @return A version number
112 | */
113 | public short getVersion() {
114 | return version;
115 | }
116 |
117 | /**
118 | * Get any flags associated with this game-lump
119 | * @return Flags, represented as a single number
120 | */
121 | public short getFlags() {
122 | return flags;
123 | }
124 |
125 | /**
126 | * Get the game-lump's numeric ID
127 | * @return The ID
128 | */
129 | public int getId() {
130 | return id;
131 | }
132 |
133 | @Override
134 | public boolean equals(Object obj) {
135 | if (obj == null) {
136 | return false;
137 | }
138 | if (getClass() != obj.getClass()) {
139 | return false;
140 | }
141 | final GameLumpHeader other = (GameLumpHeader) obj;
142 | if (this.offset != other.offset) {
143 | return false;
144 | }
145 | if (this.length != other.length) {
146 | return false;
147 | }
148 | if (this.version != other.version) {
149 | return false;
150 | }
151 | if (this.flags != other.flags) {
152 | return false;
153 | }
154 | if (this.id != other.id) {
155 | return false;
156 | }
157 | return true;
158 | }
159 |
160 | @Override
161 | public int hashCode() {
162 | int hash = 7;
163 | hash = 73 * hash + this.offset;
164 | hash = 73 * hash + this.length;
165 | hash = 73 * hash + this.version;
166 | hash = 73 * hash + this.flags;
167 | hash = 73 * hash + this.id;
168 | return hash;
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/bsp/GamePropSection.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.bsp;
14 |
15 | import com.technofovea.hl2parse.Vector3f;
16 | import java.nio.ByteBuffer;
17 |
18 | /**
19 | * Parses and encapsulates data for an item in the "props" game-lump, allowing access
20 | * to information about "static" props which are compiled into
21 | * the map.
22 | *
23 | * @author Darien Hager
24 | */
25 | public class GamePropSection {
26 |
27 | private Vector3f origin;
28 | private Vector3f rotation;
29 | private int propNameIndex;
30 | private int firstLeaf;
31 | private int leafCount;
32 | private byte solid;
33 | private byte flags;
34 | private int skin;
35 | private float fadeMinDist;
36 | private float fadeMaxDist;
37 | private Vector3f lightingOrigin;
38 | private float forcedFadeScale = 0f;
39 | private byte[] unknown1 = new byte[4];
40 |
41 | /**
42 | * Creates a new game-prop entry by pulling data from the given buffer.
43 | *
44 | * @param hdr The header file to use for version information
45 | * @param buf The game-lump data to parse from. When finished the buffer's
46 | * position should already be advanced to the next prop or to the end.
47 | */
48 | public GamePropSection(GameLumpHeader hdr, ByteBuffer buf) {
49 |
50 | origin = new Vector3f(buf);
51 | rotation = new Vector3f(buf); // Actually a euler rotation
52 | propNameIndex = buf.getShort();
53 | firstLeaf = buf.getShort();
54 | leafCount = buf.getShort();
55 | solid = buf.get();
56 | flags = buf.get();
57 |
58 | skin = buf.getInt();
59 | fadeMinDist = buf.getFloat();
60 | fadeMaxDist = buf.getFloat();
61 |
62 | lightingOrigin = new Vector3f(buf);
63 | if (hdr.getVersion() >= 5) {
64 | forcedFadeScale = buf.getFloat();
65 | }
66 | if (hdr.getVersion() >= 6) {
67 | buf.get(unknown1);
68 | }
69 | }
70 |
71 | /**
72 | * Gets the maximum fade distance
73 | * @return The distance at which this prop completely fades out
74 | */
75 | public float getFadeMaxDist() {
76 | return fadeMaxDist;
77 | }
78 |
79 | /**
80 | * Gets the minimum fade distance
81 | * @return The distance at which this prop begins to fade out.
82 | */
83 | public float getFadeMinDist() {
84 | return fadeMinDist;
85 | }
86 |
87 | public int getFirstLeaf() {
88 | return firstLeaf;
89 | }
90 |
91 | /**
92 | * Retrieves any flags associated with this prop as a byte
93 | * @return A byte representing eight boolean flags.
94 | */
95 | public byte getFlags() {
96 | return flags;
97 | }
98 |
99 | public float getForcedFadeScale() {
100 | return forcedFadeScale;
101 | }
102 |
103 | public int getLeafCount() {
104 | return leafCount;
105 | }
106 |
107 | public Vector3f getLightingOrigin() {
108 | return lightingOrigin;
109 | }
110 |
111 | /**
112 | * Get the origin of the prop
113 | * @return The origin in X,Y,Z coordinates
114 | */
115 | public Vector3f getOrigin() {
116 | return origin;
117 | }
118 |
119 | /**
120 | * Get the index number used for identifying this prop among the list of
121 | * names embedded elsewhere in the file.
122 | * @return The index ID for this prop within a map
123 | */
124 | public int getPropNameIndex() {
125 | return propNameIndex;
126 | }
127 |
128 | public Vector3f getRotation() {
129 | return rotation;
130 | }
131 |
132 | /**
133 | * Get the skin ID associated with this prop
134 | * @return A zero-indexed skin ID
135 | */
136 | public int getSkin() {
137 | return skin;
138 | }
139 |
140 | public byte getSolid() {
141 | return solid;
142 | }
143 |
144 | public byte[] getUnknown1() {
145 | return unknown1;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/bsp/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Contains classes for interpreting binary data in Source maps.
4 |
5 | These classes are geared towards reading information about static props and
6 | brush textures.
7 |
8 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/mdl/ModelFlag.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.mdl;
14 |
15 | /**
16 | *
17 | * @author Darien Hager
18 | */
19 | public enum ModelFlag {
20 |
21 | /**
22 | * This flag is set if no hitbox information was specified
23 | */
24 | STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX(0),
25 | /**
26 | * NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild
27 | * models when we change materials.
28 | */
29 | STUDIOHDR_FLAGS_USES_ENV_CUBEMAP(1),
30 | /**
31 | * Use this when there are translucent parts to the model but we're not going to sort it
32 | */
33 | STUDIOHDR_FLAGS_FORCE_OPAQUE(2),
34 | /**
35 | * Use this when we want to render the opaque parts during the opaque pass
36 | * and the translucent parts during the translucent pass
37 | */
38 | STUDIOHDR_FLAGS_TRANSLUCENT_TWOPASS(3),
39 | /**
40 | * This is set any time the .qc files has $staticprop in it
41 | * Means there's no bones and no transforms
42 | */
43 | STUDIOHDR_FLAGS_STATIC_PROP(4),
44 | /**
45 | * NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild
46 | * models when we change materials.
47 | */
48 | STUDIOHDR_FLAGS_USES_FB_TEXTURE(5),
49 | /**
50 | * This flag is set by studiomdl.exe if a separate "$shadowlod" entry was present
51 | * for the .mdl (the shadow lod is the last entry in the lod list if present)
52 | */
53 | STUDIOHDR_FLAGS_HASSHADOWLOD(6),
54 | /**
55 | * NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild
56 | * models when we change materials.
57 | */
58 | STUDIOHDR_FLAGS_USES_BUMPMAPPING(7),
59 | /**
60 | * NOTE: This flag is set when we should use the actual materials on the shadow LOD
61 | * instead of overriding them with the default one (necessary for translucent shadows)
62 | */
63 | STUDIOHDR_FLAGS_USE_SHADOWLOD_MATERIALS(8),
64 | /**
65 | * NOTE: This flag is set when we should use the actual materials on the shadow LOD
66 | * instead of overriding them with the default one (necessary for translucent shadows)
67 | */
68 | STUDIOHDR_FLAGS_OBSOLETE(9),
69 | STUDIOHDR_FLAGS_UNUSED(10),
70 | /**
71 | * NOTE: This flag is set at mdl build time
72 | */
73 | STUDIOHDR_FLAGS_NO_FORCED_FADE(11),
74 | /**
75 | * NOTE: The npc will lengthen the viseme check to always include two phonemes
76 | */
77 | STUDIOHDR_FLAGS_FORCE_PHONEME_CROSSFADE(12),
78 | /**
79 | * This flag is set when the .qc has $constantdirectionallight in it
80 | * If set, we use constantdirectionallightdot to calculate light intensity
81 | * rather than the normal directional dot product
82 | * only valid if STUDIOHDR_FLAGS_STATIC_PROP is also set
83 | */
84 | STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT(13),
85 | /**
86 | * Flag to mark delta flexes as already converted from disk format to memory format
87 | */
88 | STUDIOHDR_FLAGS_FLEXES_CONVERTED(14),
89 | /**
90 | * Indicates the studiomdl was built in preview mode
91 | */
92 | STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE(15),
93 | /**
94 | * Ambient boost (runtime flag)
95 | */
96 | STUDIOHDR_FLAGS_AMBIENT_BOOST(16),
97 | /**
98 | * Don't cast shadows from this model (useful on first-person models)
99 | */
100 | STUDIOHDR_FLAGS_DO_NOT_CAST_SHADOWS(17),
101 | /**
102 | * alpha textures should cast shadows in vrad on this model (ONLY prop_static!)
103 | */
104 | STUDIOHDR_FLAGS_CAST_TEXTURE_SHADOWS(18),;
105 | private int bitIndex;
106 |
107 | private ModelFlag(int bitIndex) {
108 | this.bitIndex = bitIndex;
109 | }
110 |
111 | public int getBitIndex() {
112 | return bitIndex;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/mdl/ModelParseException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.mdl;
14 |
15 | /**
16 | *
17 | * @author Darien Hager
18 | */
19 | public class ModelParseException extends Exception {
20 |
21 | public ModelParseException(Throwable cause) {
22 | super(cause);
23 | }
24 |
25 | public ModelParseException(String message, Throwable cause) {
26 | super(message, cause);
27 | }
28 |
29 | public ModelParseException(String message) {
30 | super(message);
31 | }
32 |
33 | public ModelParseException() {
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/mdl/ModelSection.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.mdl;
14 |
15 | /**
16 | * Enumerates various sections within a model MDL file
17 | * @author Darien Hager
18 | */
19 | public enum ModelSection {
20 |
21 | BONE,
22 | BONECONTROLLER,
23 | HITBOXSET,
24 | LOCALANIM,
25 | LOCALSEQ,
26 | TEXTURE,
27 | CDTEXTURE,
28 | SKIN,
29 | BODYPART,
30 | LOCALATTACHMENT,
31 | LOCALNODE,
32 | LOCALNODENAME,
33 | FLEXDESC,
34 | FLEXCONTROLLER,
35 | FLEXRULE,
36 | IKCHAIN,
37 | MOUTH,
38 | LOCALPOSEPARAM,
39 | SURFACEPROP,
40 | KEYVALUE,
41 | LOCALIKAUTOPLAYLOCK,
42 | INCLUDEMODEL,
43 | SZANIMBLOCKNAME,
44 | ANIMBLOCK,
45 | BONETABLEBYNAME,
46 | UNUSED4,
47 | FLEXCONTROLLERUI,
48 | STUDIOHDR2,
49 |
50 | ;
51 | }
52 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/mdl/PhyData.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 |
14 | package com.technofovea.hl2parse.mdl;
15 |
16 | import com.technofovea.hl2parse.ParseUtil;
17 | import java.nio.BufferUnderflowException;
18 | import java.nio.ByteBuffer;
19 | import java.nio.ByteOrder;
20 | import java.nio.CharBuffer;
21 | import java.nio.charset.Charset;
22 | import java.util.BitSet;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 |
26 | /**
27 | * Interprets a PHY file.
28 | * @author Darien Hager
29 | */
30 | public class PhyData {
31 |
32 | protected static final Charset CHARSET = Charset.forName("ASCII");
33 | private static final Logger logger = LoggerFactory.getLogger(PhyData.class);
34 | ByteBuffer bb;
35 | int id = -1;
36 | int checksum = 0;
37 | int solidCount = 0;
38 | ByteBuffer[] collisionSections = null;
39 | String propData = null;
40 |
41 | public PhyData(ByteBuffer bb) throws PhyParseException {
42 | this.bb = bb;
43 | bb.order(ByteOrder.LITTLE_ENDIAN);
44 | logger.debug("Parsing phy data, {} remaining", this.bb.remaining());
45 | try {
46 | load();
47 | } catch (BufferUnderflowException bue) {
48 | throw new PhyParseException(bue);
49 | }
50 | }
51 |
52 | private void load() {
53 |
54 | int hdrsize = readInt();
55 | id = readInt();
56 | solidCount = readInt();
57 | checksum = bb.getInt();
58 |
59 | int extra = (hdrsize) - bb.position();
60 | if (extra > 0) {
61 | bb.position(bb.position() + extra);
62 | }
63 |
64 | collisionSections = new ByteBuffer[solidCount];
65 |
66 | for (int i = 0; i < collisionSections.length; i++) {
67 | int len = bb.getInt();
68 | int oldLimit = bb.limit();
69 | bb.limit(bb.position() + len);
70 | ByteBuffer sectionData = bb.slice();
71 | sectionData.order(ByteOrder.LITTLE_ENDIAN);
72 |
73 | bb.position(bb.limit());
74 | bb.limit(oldLimit);
75 | collisionSections[i] = sectionData;
76 | }
77 | propData = ParseUtil.readString(bb, bb.remaining());
78 | //propData = cb.toString();
79 |
80 |
81 |
82 |
83 | }
84 |
85 | private int readShort() {
86 | return bb.getShort();
87 | }
88 |
89 | private int readInt() {
90 | return bb.getInt();
91 | }
92 |
93 | private byte[] readBytes(int count) {
94 | byte[] ret = new byte[count];
95 | bb.get(ret);
96 | return ret;
97 | }
98 |
99 | private byte readByte() {
100 | return bb.get();
101 | }
102 |
103 | private float readFloat() {
104 | return bb.getFloat();
105 | }
106 |
107 | private String readString(int len) {
108 | return ParseUtil.readString(bb, len);
109 | }
110 |
111 | private int[] readIntArray(int size) {
112 | int[] ret = new int[size];
113 | for (int i = 0; i < ret.length; i++) {
114 | ret[i] = bb.getInt();
115 | }
116 | return ret;
117 | }
118 |
119 |
120 | public int getChecksum() {
121 | return checksum;
122 | }
123 |
124 | public ByteBuffer[] getCollisionSections() {
125 | return collisionSections;
126 | }
127 |
128 | public int getId() {
129 | return id;
130 | }
131 |
132 | public String getPropData() {
133 | return propData;
134 | }
135 |
136 | public int getSolidCount() {
137 | return solidCount;
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/mdl/PhyParseException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.mdl;
14 |
15 | /**
16 | *
17 | * @author Darien Hager
18 | */
19 | public class PhyParseException extends Exception {
20 |
21 | public PhyParseException(Throwable cause) {
22 | super(cause);
23 | }
24 |
25 | public PhyParseException(String message, Throwable cause) {
26 | super(message, cause);
27 | }
28 |
29 | public PhyParseException(String message) {
30 | super(message);
31 | }
32 |
33 | public PhyParseException() {
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/mdl/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Classes to interpret the source MDL model file format.
4 |
5 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/BlobDword.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import com.technofovea.hl2parse.ParseUtil;
16 | import java.nio.ByteBuffer;
17 |
18 | /**
19 | *
20 | * @author Darien Hager
21 | */
22 | public class BlobDword extends BlobValue{
23 |
24 | byte[] dword;
25 |
26 | public BlobDword(String name, ByteBuffer realValue) {
27 | super(name);
28 | dword = new byte[4];
29 | realValue.get(dword);
30 | }
31 |
32 | @Override
33 | public DataType getType() {
34 | return DataType.DWORD;
35 | }
36 |
37 | public byte[] getDword() {
38 | return dword;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return (getName()+":"+ParseUtil.toHex(dword));
44 | }
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/BlobFolder.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import java.nio.ByteBuffer;
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | /**
20 | *
21 | * @author Darien Hager
22 | */
23 | public class BlobFolder extends BlobNode{
24 |
25 | public enum FolderItemType{
26 | FOLDER(1),
27 | FILE(2);
28 |
29 | public static FolderItemType fromNumber(int typeNum){
30 | for(FolderItemType t: FolderItemType.values()){
31 | if(t.getNumericCode() == typeNum){
32 | return t;
33 | }
34 | }
35 | return null;
36 | }
37 | public static FolderItemType fromDescriptor(ByteBuffer meta) {
38 | int typeNum = meta.get();
39 | return fromNumber(typeNum);
40 | }
41 |
42 | private int num;
43 | private FolderItemType(int num) {
44 | this.num = num;
45 | }
46 | public int getNumericCode(){
47 | return num;
48 | }
49 |
50 | }
51 |
52 |
53 | String name;
54 | Map folders = new HashMap();
55 | Map values = new HashMap();
56 | public BlobFolder(String name) {
57 | this.name=name;
58 | }
59 |
60 | public Map getFolders() {
61 | return folders;
62 | }
63 |
64 | public Map getValues() {
65 | return values;
66 | }
67 |
68 | public String getName() {
69 | return name;
70 | }
71 |
72 | @Override
73 | public String toString() {
74 | return "{"+getName()+":"+values.toString()+","+folders.toString()+"}";
75 | }
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/BlobNode.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import java.nio.ByteBuffer;
16 |
17 | /**
18 | *
19 | * @author Darien Hager
20 | */
21 | public abstract class BlobNode {
22 |
23 | ByteBuffer sourceBuffer = null;
24 |
25 | public boolean hasSourceBuffer() {
26 | return sourceBuffer != null;
27 | }
28 |
29 | //TODO write to buffer
30 | }
31 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/BlobParseFailure.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | /**
16 | *
17 | * @author Darien Hager
18 | */
19 | public class BlobParseFailure extends Exception{
20 |
21 | public BlobParseFailure(Throwable cause) {
22 | super(cause);
23 | }
24 |
25 | public BlobParseFailure(String message, Throwable cause) {
26 | super(message, cause);
27 | }
28 |
29 | public BlobParseFailure(String message) {
30 | super(message);
31 | }
32 |
33 | public BlobParseFailure() {
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/BlobRaw.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import java.lang.ref.WeakReference;
16 | import java.nio.ByteBuffer;
17 |
18 | /**
19 | *
20 | * @author Darien Hager
21 | */
22 | public class BlobRaw extends BlobValue {
23 |
24 | ByteBuffer data;
25 | WeakReference byteVersion = null;
26 |
27 | public BlobRaw(String name, ByteBuffer realValue) {
28 | super(name);
29 | data = realValue.asReadOnlyBuffer();
30 |
31 | }
32 |
33 | @Override
34 | public DataType getType() {
35 | return DataType.RAW;
36 | }
37 |
38 | public ByteBuffer asBuffer() {
39 | return data;
40 | }
41 |
42 | public synchronized byte[] getRaw() {
43 | byte[] cached = byteVersion.get();
44 | if (cached != null) {
45 | return cached;
46 | } else {
47 | data.clear();
48 | byte[] raw = new byte[data.remaining()];
49 | data.get(raw);
50 | byteVersion = new WeakReference(raw);
51 | return raw;
52 | }
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/BlobText.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import java.nio.ByteBuffer;
16 |
17 | /**
18 | *
19 | * @author Darien Hager
20 | */
21 | public class BlobText extends BlobValue{
22 |
23 | String text;
24 |
25 | public BlobText(String name, ByteBuffer realValue) {
26 | super(name);
27 | text = RegParser.getText(realValue);
28 | }
29 |
30 | @Override
31 | public DataType getType() {
32 | return DataType.TEXT;
33 | }
34 |
35 | public String getText() {
36 | return text;
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return (getName()+":"+getText());
42 | }
43 |
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/BlobValue.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import java.nio.ByteBuffer;
16 |
17 | /**
18 | *
19 | * @author Darien Hager
20 | */
21 | public abstract class BlobValue extends BlobNode {
22 | public enum DataType{
23 | TEXT(0),
24 | DWORD(1),
25 | RAW(2);
26 |
27 | public static DataType fromNumber(int typeNum){
28 | for(DataType t: DataType.values()){
29 | if(t.getNumericCode() == typeNum){
30 | return t;
31 | }
32 | }
33 | return null;
34 | }
35 | public static DataType fromDescriptor(ByteBuffer meta) {
36 | int typeNum = meta.get();
37 | return fromNumber(typeNum);
38 | }
39 |
40 | private int num;
41 | private DataType(int num) {
42 | this.num = num;
43 | }
44 | public int getNumericCode(){
45 | return num;
46 | }
47 |
48 |
49 | }
50 |
51 | String name;
52 |
53 | public BlobValue(String name) {
54 | this.name = name;
55 | }
56 |
57 | public abstract DataType getType();
58 |
59 | public String getName() {
60 | return name;
61 | }
62 |
63 |
64 |
65 |
66 |
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/CellCollection.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import com.technofovea.hl2parse.registry.CellItem;
16 | import java.nio.ByteBuffer;
17 | import java.util.ArrayList;
18 | import java.util.Iterator;
19 | import java.util.List;
20 |
21 | /**
22 | *
23 | * @author Darien Hager
24 | */
25 | public class CellCollection implements Iterable{
26 | List items = new ArrayList();
27 | int underflow = 0;
28 |
29 | public Iterator iterator() {
30 | return items.iterator();
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/CellItem.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import java.nio.ByteBuffer;
16 |
17 | class CellItem {
18 |
19 | CellItem(ByteBuffer meta, ByteBuffer payload) {
20 | super();
21 | this.meta = meta;
22 | this.payload = payload;
23 | }
24 | private ByteBuffer meta;
25 | private ByteBuffer payload;
26 |
27 | /**
28 | * @return the meta
29 | */
30 | public ByteBuffer getMeta() {
31 | return meta;
32 | }
33 |
34 | /**
35 | * @return the payload
36 | */
37 | public ByteBuffer getPayload() {
38 | return payload;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/ClientRegistry.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import com.technofovea.hl2parse.JxPathUtil;
16 | import java.nio.ByteBuffer;
17 | import java.util.ArrayList;
18 | import java.util.Iterator;
19 | import java.util.List;
20 | import org.apache.commons.jxpath.JXPathContext;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 |
24 | /**
25 | *
26 | * @author Darien Hager
27 | */
28 | public class ClientRegistry {
29 |
30 | private static final Logger logger = LoggerFactory.getLogger(ClientRegistry.class);
31 | protected static final String CDR_SECTION_NAME = "ContentDescriptionRecord";
32 | BlobFolder root;
33 | CdrParser cdr = null;
34 | JXPathContext ctx;
35 |
36 | public ClientRegistry(BlobFolder root) throws BlobParseFailure {
37 | this.root = root;
38 | ctx = JXPathContext.newContext(root);
39 | JxPathUtil.addFunctions(ctx);
40 | cdr = createCdr();
41 | }
42 |
43 | CdrParser createCdr() throws BlobParseFailure {
44 | logger.debug("Finding compressed " + CDR_SECTION_NAME + " section");
45 | BlobRaw br = (BlobRaw) ctx.getValue("/values[@name='" + CDR_SECTION_NAME + "']");
46 | if (br == null) {
47 | throw new BlobParseFailure("Could not find " + CDR_SECTION_NAME + " segment. Check that Steam is up-to-date.");
48 | }
49 |
50 | logger.debug("Extracting compressed CDR section");
51 | ByteBuffer expandedBuf = RegParser.decompress(br.asBuffer());
52 |
53 | logger.debug("Creating reader for decompressed CDR data");
54 | CdrParser cp = new CdrParser(expandedBuf);
55 | return cp;
56 | }
57 |
58 | public CdrParser getContentDescriptionRecord() {
59 | return cdr;
60 | }
61 |
62 | public JXPathContext getRootContext() {
63 | return ctx;
64 | }
65 |
66 | public List getUsernames() {
67 | logger.debug("Retrieving known Steam username(s)");
68 |
69 | Iterator users = (Iterator) ctx.iterate("/folders[@name='_Users']/folders/*/name");
70 | List ret = new ArrayList();
71 | while (users.hasNext()) {
72 | ret.add(users.next());
73 | }
74 | logger.debug("Usernames found: {}", ret);
75 | return ret;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/hl2parse-binary/src/main/java/com/technofovea/hl2parse/registry/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Classes for interpreting metadata within Steam's clientregistry.blob file.
4 |
5 |
--------------------------------------------------------------------------------
/hl2parse-common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | com.technofovea
7 | hl2parse
8 | 1.2.2-SNAPSHOT
9 | ../pom.xml
10 |
11 |
12 | hl2parse-common
13 | hl2parse-common
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | commons-jxpath
22 | commons-jxpath
23 |
24 |
25 |
26 | junit
27 | junit
28 | test
29 |
30 |
31 |
32 | org.slf4j
33 | slf4j-api
34 |
35 |
36 | org.slf4j
37 | slf4j-log4j12
38 |
39 |
40 |
41 |
42 |
43 | ${basedir}/..
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/JxPathUtil.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse;
14 |
15 | import org.apache.commons.jxpath.ClassFunctions;
16 | import org.apache.commons.jxpath.JXPathContext;
17 |
18 | /**
19 | * This utility class provides a few simple methods for dealing with JXPath
20 | * expressions.
21 | *
22 | * @author Darien Hager
23 | */
24 | public class JxPathUtil {
25 |
26 | /**
27 | * Adds custom functions onto a context which correspond to
28 | * static methods on this class, such as {@link #startswith(java.lang.String, java.lang.String)}
29 | * @param context The context to alter.
30 | */
31 | public static void addFunctions(JXPathContext context) {
32 | context.setFunctions(new ClassFunctions(JxPathUtil.class, "custom"));
33 | }
34 |
35 | /**
36 | * A convenience function, this performs a *case-insensitive* equality test,
37 | * unlike the normal [a=b] xpath convention.
38 | * @param a A string
39 | * @param b A string
40 | * @return True if the two strings are equal, ignoring case. False otherwise.
41 | */
42 | public static boolean equals(String a, String b) {
43 | if (a == null) {
44 | return false;
45 | }
46 | return a.equalsIgnoreCase(b);
47 | }
48 |
49 | /**
50 | * This function performs a case-insensitive starts-with test.
51 | * @param s The string to examine
52 | * @param prefix The prefix to try
53 | * @return True if the first string starts with the second, ignoring case.
54 | */
55 | public static boolean startswith(String s, String prefix) {
56 | if (s == null || prefix == null) {
57 | return false;
58 | }
59 | return s.toLowerCase().startsWith(prefix.toLowerCase());
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/entdata/DefaultPathFixer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.entdata;
14 |
15 | /**
16 | * A default implementation of {@link PathFixer}, this singleton attempts to
17 | * correct material, sound, and sprite paths. In some cases the sprite/material
18 | * distinction is ambiguous, and no extension is added.
19 | *
20 | * @author Darien Hager
21 | */
22 | public class DefaultPathFixer implements PathFixer {
23 |
24 | private static DefaultPathFixer instance;
25 |
26 | String nonPathPrefix = ":";
27 |
28 | private DefaultPathFixer() {
29 | }
30 |
31 | /**
32 | * Get the singleton instance of this fixer
33 | * @return The singleton
34 | */
35 | public static DefaultPathFixer getInstance() {
36 | synchronized (DefaultPathFixer.class) {
37 | if (instance == null) {
38 | instance = new DefaultPathFixer();
39 | }
40 | }
41 | return instance;
42 |
43 | }
44 |
45 | public String fixPath(String origPath,ValueSource src) {
46 | if(DependencyFinder.PROPTYPE_MATERIAL.equalsIgnoreCase(src.getDataType())){
47 | return fixMaterial(origPath,src);
48 | }else if(DependencyFinder.PROPTYPE_SOUND.equalsIgnoreCase(src.getDataType())){
49 | return fixSound(origPath,src);
50 | }else if(DependencyFinder.PROPTYPE_SPRITE.equalsIgnoreCase(src.getDataType())){
51 | return fixMaterial(origPath, src);
52 | }else if(DependencyFinder.PROPTYPE_DECAL.equalsIgnoreCase(src.getDataType())){
53 | return fixMaterial(origPath,src);
54 | }else if("vtf".equalsIgnoreCase(src.getDataType())){
55 | return fixTexture(origPath,src);
56 | }
57 | return origPath;
58 | }
59 |
60 |
61 | private String fixMaterial(String origPath, ValueSource src) {
62 | String path = origPath;
63 | path = path.replace("\\", "/");
64 | if (!path.toLowerCase().endsWith(".vmt") && !path.toLowerCase().endsWith(".spr")) {
65 | path = path + ".vmt";
66 | }
67 | if (!path.toLowerCase().startsWith("materials/")) {
68 | path = "materials/" + path;
69 | }
70 | return path;
71 | }
72 |
73 | private String fixTexture(String origPath, ValueSource src) {
74 | String path = origPath;
75 | path = path.replace("\\", "/");
76 | if (!path.toLowerCase().endsWith(".vtf")) {
77 | path = path + ".vtf";
78 | }
79 | if (!path.toLowerCase().startsWith("materials/")) {
80 | path = "materials/" + path;
81 | }
82 | return path;
83 | }
84 |
85 | private String fixSound(String origPath, ValueSource src) {
86 | String path = origPath;
87 | path = path.replace("\\", "/");
88 | if(!path.contains("/") && !path.toLowerCase().endsWith(".wav")){
89 | // Probably a symbolic sound, like Ambient.Hum
90 | return getNonPathPrefix() + origPath;
91 | }
92 | if(!path.toLowerCase().endsWith(".wav")){
93 | path = path + ".wav";
94 | }
95 | if(!path.toLowerCase().startsWith("sound/")){
96 | path = "sound/" + path;
97 | }
98 | return path;
99 | }
100 |
101 | /**
102 | * Get the string prefix which is added when a non-path value is encountered
103 | * @return A string prefix
104 | */
105 | public String getNonPathPrefix() {
106 | return nonPathPrefix;
107 | }
108 |
109 | /**
110 | * Set the string prefix to be added when a non-path value is encountered
111 | * @param nonPathPrefix A string to prefix non-paths with, ideally a value
112 | * which will be unambiguous when seen.
113 | */
114 | public void setNonPathPrefix(String nonPathPrefix) {
115 | this.nonPathPrefix = nonPathPrefix;
116 | }
117 |
118 |
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/entdata/EntdataException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.entdata;
14 |
15 | /**
16 | * Thrown when there is a problem parsing entity data.
17 | * @author Darien Hager
18 | */
19 | public class EntdataException extends Exception {
20 |
21 | public EntdataException(Throwable cause) {
22 | super(cause);
23 | }
24 |
25 | public EntdataException(String message, Throwable cause) {
26 | super(message, cause);
27 | }
28 |
29 | public EntdataException(String message) {
30 | super(message);
31 | }
32 |
33 | public EntdataException() {
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/entdata/MapEntity.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.entdata;
14 |
15 | import com.technofovea.hl2parse.vdf.VdfAttribute;
16 | import com.technofovea.hl2parse.vdf.VdfNode;
17 | import java.util.ArrayList;
18 | import java.util.HashMap;
19 | import java.util.HashSet;
20 | import java.util.List;
21 | import java.util.Map;
22 | import java.util.Set;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 |
26 | /**
27 | * Represents a single entity found within a map.
28 | *
29 | * @author Darien Hager
30 | */
31 | public class MapEntity {
32 |
33 | private static final Logger logger = LoggerFactory.getLogger(MapEntity.class);
34 | static String KEY_CLASS = "classname";
35 | static String KEY_ID = "hammerid";
36 | /**
37 | * The class-name of this entity
38 | */
39 | protected String entityClass = null;
40 | /**
41 | * The optional Hammer-ID of this entity, or -1 if none found.
42 | */
43 | protected int hammerId = -1;
44 | /**
45 | * The property keys and values associated with this entity. Note that in
46 | * several situations it is permissible for multiple key/value pairs using
47 | * the same key.
48 | */
49 | protected Map> attrs = new HashMap>();
50 |
51 | /**
52 | * Creates a new list of entity objects after the map entity data has been
53 | * parsed into a {@link VdfNode} tree.
54 | * @param rootNode The root node for the tree.
55 | * @return A list of map entities, possibly blank.
56 | * @throws EntdataException If there was a problem interpreting the tree.
57 | */
58 | public static List fromVdf(VdfNode rootNode) throws EntdataException {
59 | List entities = new ArrayList();
60 | for (VdfNode entNode : rootNode.getChildren()) {
61 | MapEntity e = new MapEntity(entNode);
62 | entities.add(e);
63 | }
64 | return entities;
65 | }
66 |
67 | /**
68 | * Creates a new map entity with the given keys and values. Keys are
69 | * automatically checked for class-name information.
70 | *
71 | * @param attributes All attributes on this entity, including class-name and
72 | * other "special" values.
73 | * @throws EntdataException If there was a problem interpreting the data.
74 | */
75 | public MapEntity(Map> attributes) throws EntdataException {
76 | if (!attributes.containsKey(KEY_CLASS)) {
77 | throw new EntdataException("No class-name specified for entity");
78 | }
79 | if (!(attributes.get(KEY_CLASS).size() < 1)) {
80 | throw new EntdataException("No class-name specified for entity");
81 | }
82 |
83 | entityClass = attributes.remove(KEY_CLASS).get(0).toLowerCase().trim();
84 | for (String key : attributes.keySet()) {
85 | key = key.trim().toLowerCase();
86 | List vals = attributes.get(key);
87 | if (key.equalsIgnoreCase(KEY_ID)) {
88 |
89 | try {
90 | hammerId = Integer.parseInt(vals.get(0).toLowerCase());
91 | } catch (NumberFormatException nfe) {
92 | throw new EntdataException("Invalid hammer ID: " + vals);
93 | }
94 | } else {
95 | if(vals.size()>0){
96 | this.attrs.put(key, vals);
97 | }//TODO log?
98 | }
99 | }
100 |
101 | }
102 |
103 | /**
104 | * Creates a new map entity from an isolated {@link VdfNode}
105 | *
106 | * @param entityNode The node containing key/value mappings describing the entity.
107 | * @throws EntdataException If there was a problem interpreting the data.
108 | */
109 | public MapEntity(VdfNode entityNode) throws EntdataException {
110 |
111 | if (entityNode.getChildren().size() > 0) {
112 | throw new EntdataException("Entity nodes may not have child blocks, but " + entityNode.getChildren().size() + " found.");
113 | }
114 | for (VdfAttribute attr : entityNode.getAttributes()) {
115 | String key = attr.getName().toLowerCase().trim();
116 | String val = attr.getValue();
117 |
118 |
119 |
120 | if (key.equalsIgnoreCase(KEY_CLASS)) {
121 | entityClass = val.toLowerCase();
122 | } else if (key.equalsIgnoreCase(KEY_ID)) {
123 | try {
124 | hammerId = Integer.parseInt(val.toLowerCase());
125 | } catch (NumberFormatException nfe) {
126 | throw new EntdataException("Invalid hammer ID: " + val);
127 | }
128 | } else {
129 | if (!attrs.containsKey(key)) {
130 | attrs.put(key, new ArrayList());
131 | }
132 | attrs.get(key).add(val);
133 |
134 |
135 | }
136 | }
137 | if (entityClass == null) {
138 | throw new EntdataException("No entity class found");
139 | }
140 | if (hammerId == -1) {
141 | // Apparently this isn't the terrible case I thought it was.
142 | }
143 | }
144 | /**
145 | * Retrieve the class-name of this entity (ex. prop_dynamic)
146 | * @return The class-name
147 | */
148 | public String getEntityClass() {
149 | return entityClass;
150 | }
151 |
152 | /**
153 | * Retrieve the hammer-ID for this entity.
154 | * @return A hammer-ID or -1 if not found
155 | */
156 | public int getHammerId() {
157 | return hammerId;
158 | }
159 |
160 | /**
161 | * Gets a set of all property-names on this entity. Note that this does not
162 | * include "special" values like the class-name or hammer-id.
163 | * @return A set of property names.
164 | */
165 | public Set getKeys() {
166 | return new HashSet(attrs.keySet());
167 | }
168 |
169 | /**
170 | * Check if the given property-name is defined for this entity.
171 | * @param propertyName The property-name to check.
172 | * @return True if found, false otherwise.
173 | */
174 | public boolean containsKey(String propertyName) {
175 | return attrs.containsKey(propertyName);
176 | }
177 |
178 | /**
179 | * Retrieves the list of values associated with a particular property name
180 | * on this entity, or null if none found.
181 | * @param propertyName The property-name to retrieve data for.
182 | * @return A list of values set for the given property.
183 | */
184 | public List getValues(String propertyName) {
185 | return new ArrayList(attrs.get(propertyName));
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/entdata/PathFixer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.entdata;
14 |
15 | /**
16 | * A PathFixer is responsible for taking strings (and associated
17 | * {@link ValueSource} objects) and returning a "proper" path. For example, a
18 | * material may be found as "folder/file", lacking the implicit parts that would
19 | * turn it into "materials/folder/file.vmt".
20 | *
21 | * @author Darien Hager
22 | */
23 | public interface PathFixer {
24 |
25 | /**
26 | * Given a string and details about where it was found, attempt to convert
27 | * it into a relative file path.
28 | *
29 | * If the value does not correspond to a file path (such as symbolic sound
30 | * names like Ambient.Hum) then a string is returned beginning with the
31 | * non-path prefix.
32 | *
33 | * @param origPath The original path or string
34 | * @param src The source where it was found
35 | * @return A relative path or
36 | */
37 | public String fixPath(String origPath, ValueSource src);
38 |
39 | /**
40 | * Returns a string used by {@link #fixPath(java.lang.String, com.technofovea.hl2parse.entdata.ValueSource)}
41 | * to prefix non-path values. Typically this should be a character which is
42 | * not part of any typical valid path, such as a colon.
43 | * @return The string used to prefix non-path values
44 | */
45 | public String getNonPathPrefix();
46 | }
47 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/entdata/ValueSource.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.entdata;
14 |
15 | /**
16 | * Represents a source for entity values.
17 | */
18 | public class ValueSource {
19 |
20 | /**
21 | * The entity-class to get values from
22 | */
23 | String className;
24 | /**
25 | * The property-name on the entity to get a value from
26 | */
27 | String propertyName;
28 | /**
29 | * The type (typically specified by FGD) of the value(s)
30 | */
31 | String dataType;
32 |
33 |
34 |
35 | /**
36 | * Creates a new object with the given class/property names and datatype.
37 | * @param className The class-name
38 | * @param propertyName The property-name
39 | * @param dataType The datatype for the property
40 | */
41 | public ValueSource(String className, String propertyName, String dataType) {
42 | //TODO investigate how case-sensitivity comes into play
43 | this.className = className;
44 | this.propertyName = propertyName;
45 | this.dataType = dataType;
46 | }
47 |
48 |
49 |
50 |
51 | /**
52 | * Gets the entity class-name of this source
53 | * @return An entity class name
54 | */
55 | public String getClassName() {
56 | return className;
57 | }
58 |
59 | /**
60 | * The name of the property on the entity which is being targeted
61 | * @return A string property name
62 | */
63 | public String getPropertyName() {
64 | return propertyName;
65 | }
66 |
67 | /**
68 | * Gets the data type associated with the property values
69 | * @return A string for the datatype, as used in FGDs
70 | */
71 | public String getDataType() {
72 | return dataType;
73 | }
74 |
75 |
76 |
77 |
78 | @Override
79 | public String toString() {
80 | return "{" + className + "," + propertyName + ":" + dataType + "}";
81 | }
82 |
83 | @Override
84 | public boolean equals(Object obj) {
85 | if (obj == null) {
86 | return false;
87 | }
88 | if (getClass() != obj.getClass()) {
89 | return false;
90 | }
91 | final ValueSource other = (ValueSource) obj;
92 | if ((this.className == null) ? (other.className != null) : !this.className.equalsIgnoreCase(other.className)) {
93 | return false;
94 | }
95 | if ((this.propertyName == null) ? (other.propertyName != null) : !this.propertyName.equalsIgnoreCase(other.propertyName)) {
96 | return false;
97 | }
98 | if ((this.dataType == null) ? (other.dataType != null) : !this.dataType.equalsIgnoreCase(other.dataType)) {
99 | return false;
100 | }
101 | return true;
102 | }
103 |
104 | @Override
105 | public int hashCode() {
106 | int hash = 7;
107 | hash = 97 * hash + (this.className != null ? this.className.hashCode() : 0);
108 | hash = 97 * hash + (this.propertyName != null ? this.propertyName.hashCode() : 0);
109 | hash = 97 * hash + (this.dataType != null ? this.dataType.hashCode() : 0);
110 | return hash;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/entdata/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tools for interpreting entity data for maps, and to mine that data in conjunction with FGD information.
4 |
5 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/ChoicesValue.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | /**
16 | * Represents a possible value for an FgdProperty of type "choices"
17 | * @author Darien Hager
18 | */
19 | public class ChoicesValue implements Comparable{
20 |
21 | private String value;
22 | private String description;
23 |
24 | public ChoicesValue(String value, String description) {
25 | this.value= value;
26 | this.description = description;
27 | }
28 |
29 | public String getDescription() {
30 | return description;
31 | }
32 |
33 | public String getValue() {
34 | return value;
35 | }
36 |
37 |
38 |
39 | public String toText() {
40 | String valueOutput = FgdSpec.quoteVal(value);
41 | String ret = valueOutput + ":\""+getDescription()+"\"";
42 | return ret;
43 | }
44 |
45 | public int compareTo(ChoicesValue o) {
46 | int difference = this.getValue().compareTo(o.getValue());
47 | if(difference != 0){
48 | return difference;
49 | }
50 | return this.getDescription().compareTo(o.getDescription());
51 | }
52 |
53 | @Override
54 | public boolean equals(Object obj) {
55 | if (obj == null) {
56 | return false;
57 | }
58 | if (getClass() != obj.getClass()) {
59 | return false;
60 | }
61 | final ChoicesValue other = (ChoicesValue) obj;
62 | if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
63 | return false;
64 | }
65 | if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
66 | return false;
67 | }
68 | return true;
69 | }
70 |
71 | @Override
72 | public int hashCode() {
73 | int hash = 3;
74 | hash = 23 * hash + (this.value != null ? this.value.hashCode() : 0);
75 | hash = 23 * hash + (this.description != null ? this.description.hashCode() : 0);
76 | return hash;
77 | }
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/FgdInput.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | /**
16 | * Represents an anonymous input on an entity-class.
17 | * @author Darien Hager
18 | */
19 | public class FgdInput {
20 |
21 | private static final String INPUT_QUALIFIER = "input";
22 |
23 | private String type;
24 | private String description;
25 |
26 | public FgdInput(String type) {
27 | this(type,"");
28 | }
29 |
30 | public FgdInput(String type, String description) {
31 | this.type = type;
32 | this.description = description;
33 | }
34 |
35 | public String getDescription() {
36 | return description;
37 | }
38 |
39 | public void setDescription(String description) {
40 | this.description = description;
41 | }
42 |
43 |
44 |
45 | public String getType() {
46 | return type;
47 | }
48 |
49 | public void setType(String type) {
50 | this.type = type;
51 | }
52 |
53 | public String toText(String name) {
54 | StringBuilder sb = new StringBuilder();
55 | sb.append(INPUT_QUALIFIER);
56 | sb.append(" ");
57 | sb.append(name);
58 | sb.append("(");
59 | sb.append(type);
60 | sb.append(") : \"");
61 | sb.append(description);
62 | sb.append("\" ");
63 | return sb.toString();
64 | }
65 |
66 | @Override
67 | public boolean equals(Object obj) {
68 | if (obj == null) {
69 | return false;
70 | }
71 | if (getClass() != obj.getClass()) {
72 | return false;
73 | }
74 | final FgdInput other = (FgdInput) obj;
75 | if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
76 | return false;
77 | }
78 | if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
79 | return false;
80 | }
81 | return true;
82 | }
83 |
84 | @Override
85 | public int hashCode() {
86 | int hash = 7;
87 | hash = 29 * hash + (this.type != null ? this.type.hashCode() : 0);
88 | hash = 29 * hash + (this.description != null ? this.description.hashCode() : 0);
89 | return hash;
90 | }
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/FgdOutput.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | /**
16 | * Represents an anonymous output on an entity-class.
17 | * @author Darien
18 | */
19 | public class FgdOutput {
20 |
21 | private static final String OUTPUT_QUALIFIER = "output";
22 |
23 | private String type;
24 | private String description;
25 |
26 | public FgdOutput(String type) {
27 | this(type,"");
28 | }
29 |
30 | public FgdOutput(String type, String description) {
31 | this.type = type;
32 | this.description = description;
33 | }
34 |
35 | public String getDescription() {
36 | return description;
37 | }
38 |
39 | public void setDescription(String description) {
40 | this.description = description;
41 | }
42 |
43 |
44 | public String getType() {
45 | return type;
46 | }
47 |
48 | public void setType(String type) {
49 | this.type = type;
50 | }
51 |
52 | public String toText(String name) {
53 | StringBuilder sb = new StringBuilder();
54 | sb.append(OUTPUT_QUALIFIER);
55 | sb.append(" ");
56 | sb.append(name);
57 | sb.append("(");
58 | sb.append(type);
59 | sb.append(") : \"");
60 | sb.append(description);
61 | sb.append("\" ");
62 | return sb.toString();
63 | }
64 |
65 | @Override
66 | public boolean equals(Object obj) {
67 | if (obj == null) {
68 | return false;
69 | }
70 | if (getClass() != obj.getClass()) {
71 | return false;
72 | }
73 | final FgdOutput other = (FgdOutput) obj;
74 | if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
75 | return false;
76 | }
77 | if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
78 | return false;
79 | }
80 | return true;
81 | }
82 |
83 | @Override
84 | public int hashCode() {
85 | int hash = 3;
86 | hash = 97 * hash + (this.type != null ? this.type.hashCode() : 0);
87 | hash = 97 * hash + (this.description != null ? this.description.hashCode() : 0);
88 | return hash;
89 | }
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/FgdProperty.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | /**
19 | * Represents an anonymous property on an entity-class. Certain accessors on
20 | * this class only make sense if the object's type is set correctly.
21 | * @author Darien Hager
22 | */
23 | public class FgdProperty {
24 | public static final String TYPE_CHOICES = "choices";
25 | public static final String TYPE_FLAGS = "flags";
26 |
27 | String type;
28 | boolean readonly = false;
29 | String shortDesc = "";
30 | String longDesc = "";
31 | String defaultVal = "";
32 | List flags = new ArrayList();
33 | List options = new ArrayList();
34 |
35 |
36 |
37 | public String getType() {
38 | return type;
39 | }
40 |
41 | public void setType(String type) {
42 | this.type = type;
43 | }
44 |
45 | public boolean isReadonly() {
46 | return readonly;
47 | }
48 |
49 | public void setReadonly(boolean readonly) {
50 | this.readonly = readonly;
51 | }
52 |
53 | /**
54 | * Only applicable if the type of this property is set to "flags"
55 | * @return A modifiable list of flags.
56 | */
57 | public List getFlags() {
58 | return flags;
59 | }
60 |
61 | /**
62 | * Only applicable if the type of this property is set to "choices"
63 | * @return A modifiable list of options.
64 | */
65 | public List getOptions() {
66 | return options;
67 | }
68 |
69 | public String toText(String name) {
70 |
71 | StringBuilder sb = new StringBuilder();
72 | sb.append(name);
73 | sb.append("(");
74 | sb.append(type);
75 | sb.append(") ");
76 |
77 | sb.append(": \"");
78 | sb.append(shortDesc);
79 | sb.append("\" : ");
80 |
81 | // If default value is integer, do not quote
82 | String temp = FgdSpec.quoteVal(defaultVal);
83 | sb.append(temp);
84 |
85 | sb.append(" : \"");
86 | sb.append(longDesc);
87 | sb.append("\" ");
88 |
89 | if (TYPE_CHOICES.equalsIgnoreCase(type)) {
90 | sb.append("=\n[\n");
91 | for (ChoicesValue o : options) {
92 | sb.append(o.toText());
93 | sb.append("\n");
94 | }
95 | sb.append("]");
96 | } else if (TYPE_FLAGS.equalsIgnoreCase(type)) {
97 | sb.append("=\n[\n");
98 |
99 | for (FlagValue f : flags) {
100 | sb.append(f.toText());
101 | sb.append("\n");
102 | }
103 | sb.append("]");
104 | } else {
105 | }
106 |
107 | return sb.toString();
108 | }
109 |
110 | void setShortDescription(String str) {
111 | shortDesc = str;
112 | if(shortDesc == null){
113 | shortDesc = "";
114 | }
115 | }
116 |
117 | void setLongDescription(String str) {
118 | longDesc = str;
119 | if(longDesc == null){
120 | longDesc = "";
121 | }
122 | }
123 |
124 | void setDefault(String str) {
125 | defaultVal = str;
126 | if(defaultVal == null){
127 | defaultVal = "";
128 | }
129 | }
130 |
131 | public String getDefaultVal() {
132 | return defaultVal;
133 | }
134 |
135 | public String getLongDesc() {
136 | return longDesc;
137 | }
138 |
139 | public String getShortDesc() {
140 | return shortDesc;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/FgdSpec.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | import java.util.HashMap;
16 | import java.util.HashSet;
17 | import java.util.Map;
18 | import java.util.Set;
19 |
20 | /**
21 | * Represents an FGD 'document' and associated data.
22 | * @author Darien Hager
23 | */
24 | public class FgdSpec {
25 |
26 | Map definedClasses = new HashMap();
27 | Map visGroups = new HashMap();
28 | boolean boundsSet = false;
29 | int mapMin = -32768;
30 | int mapMax = 32768;
31 | Set excludedMaterials = new HashSet();
32 |
33 | static String cleanQuotes(String input) {
34 | return input.replace("\"", " ");
35 | }
36 |
37 | static String quoteVal(String value) {
38 | try {
39 | int i = Integer.parseInt(value);
40 | return value;
41 | } catch (NumberFormatException nfe) {
42 | return "\"" + value + "\"";
43 | }
44 |
45 | }
46 |
47 |
48 | public int getMapMax() {
49 | return mapMax;
50 | }
51 |
52 | public void setMapBounds(int mapMin, int mapMax) throws IllegalArgumentException {
53 | if (mapMax < mapMin) {
54 | throw new IllegalArgumentException("Maximum value is less than minimum value");
55 | }
56 | this.mapMin = mapMin;
57 | this.mapMax = mapMax;
58 | boundsSet = true;
59 | }
60 |
61 | public void setMapBounds(String mapMin, String mapMax) throws IllegalArgumentException {
62 | int low = Integer.parseInt(mapMin);
63 | int high = Integer.parseInt(mapMax);
64 | setMapBounds(low, high);
65 | }
66 |
67 | public int getMapMin() {
68 | return mapMin;
69 | }
70 |
71 | public void addEntClass(String name, FgdEntClass item) {
72 | definedClasses.put(name, item);
73 | }
74 |
75 | public FgdEntClass getEntClass(String name) {
76 | return definedClasses.get(name);
77 | }
78 |
79 | public Set getEntClassNames() {
80 | return new HashSet(definedClasses.keySet());
81 | }
82 |
83 | public void clearEntClases() {
84 | definedClasses.clear();
85 | }
86 |
87 | public VisGroup getVisGroup(String name) {
88 | return visGroups.get(name);
89 | }
90 |
91 | public Set getVisGroupNames() {
92 | return new HashSet(visGroups.keySet());
93 | }
94 |
95 | public void addVisGroup(String name, VisGroup grp) {
96 | visGroups.put(name, grp);
97 | }
98 |
99 | public Set getExcludedMaterials() {
100 | return excludedMaterials;
101 | }
102 |
103 | public void setExcludedMaterials(Set excludedMaterials) {
104 | this.excludedMaterials = excludedMaterials;
105 | }
106 |
107 |
108 |
109 | public String toText() {
110 | StringBuilder sb = new StringBuilder();
111 | if (boundsSet) {
112 | sb.append("@mapsize(" + mapMin + "," + mapMax + ")\n");
113 | }
114 | if (excludedMaterials.size()>0){
115 | sb.append("@MaterialExclusion\n[");
116 | for(String item : excludedMaterials){
117 | sb.append(quoteVal(item));
118 | sb.append("\n");
119 | }
120 | sb.append("]\n");
121 | }
122 | for(String groupName : visGroups.keySet()){
123 | VisGroup vg = visGroups.get(groupName);
124 | sb.append("@AutoVisGroup = ");
125 | sb.append(groupName);
126 | sb.append("\n[\n");
127 | for(String subName : vg.getSectionNames()){
128 | sb.append(quoteVal(subName));
129 | sb.append("\n[\n");
130 | for(String item : vg.getSectionItems(subName)){
131 |
132 | sb.append(quoteVal(item));
133 | sb.append("\n");
134 | }
135 | sb.append("]\n");
136 | }
137 | sb.append("]\n");
138 |
139 |
140 |
141 | }
142 | for (String clazzName : definedClasses.keySet()) {
143 | FgdEntClass entClass = definedClasses.get(clazzName);
144 | sb.append(entClass.toText(clazzName));
145 | }
146 | return sb.toString();
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/FlagValue.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | /**
16 | * Represents a possible value for an FgdProperty of type "flags"
17 | * @author Darien Hager
18 | */
19 | public class FlagValue implements Comparable{
20 |
21 | private int intValue;
22 | private String name;
23 | private boolean defaultOn;
24 |
25 | public FlagValue(int intValue, String name, boolean defaultOn) {
26 | this.intValue = intValue;
27 | this.name = name;
28 | this.defaultOn = defaultOn;
29 | }
30 |
31 | public boolean isDefaultOn() {
32 | return defaultOn;
33 | }
34 |
35 | public int getIntValue() {
36 | return intValue;
37 | }
38 |
39 | public String getName() {
40 | return name;
41 | }
42 |
43 | public String toText() {
44 | String ret =getIntValue() + ":\""+getName()+"\":";
45 | if(isDefaultOn()){
46 | ret = ret + "1";
47 | }else{
48 | ret = ret + "0";
49 | }
50 | return ret;
51 | }
52 |
53 | @Override
54 | public boolean equals(Object obj) {
55 | if (obj == null) {
56 | return false;
57 | }
58 | if (getClass() != obj.getClass()) {
59 | return false;
60 | }
61 | final FlagValue other = (FlagValue) obj;
62 | if (this.intValue != other.intValue) {
63 | return false;
64 | }
65 | if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
66 | return false;
67 | }
68 | if (this.defaultOn != other.defaultOn) {
69 | return false;
70 | }
71 | return true;
72 | }
73 |
74 | @Override
75 | public int hashCode() {
76 | int hash = 7;
77 | hash = 59 * hash + this.intValue;
78 | hash = 59 * hash + (this.name != null ? this.name.hashCode() : 0);
79 | hash = 59 * hash + (this.defaultOn ? 1 : 0);
80 | return hash;
81 | }
82 |
83 | public int compareTo(FlagValue other) {
84 | int valueDifference = this.getIntValue() - other.getIntValue();
85 | if(valueDifference != 0){
86 | return valueDifference;
87 | }
88 |
89 | // Same numbers? Weird but possible, so then sort by the string.
90 | return this.getName().compareTo(other.getName());
91 | }
92 |
93 |
94 |
95 |
96 |
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/VisGroup.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | import java.util.Collection;
16 | import java.util.HashMap;
17 | import java.util.HashSet;
18 | import java.util.Map;
19 | import java.util.Set;
20 |
21 | /**
22 | *
23 | * @author Darien Hager
24 | */
25 | public class VisGroup {
26 |
27 | Map> sections = new HashMap>();
28 |
29 | public Set getSectionNames(){
30 | return new HashSet(sections.keySet());
31 | }
32 |
33 | public void removeSection(String name){
34 | sections.remove(name);
35 | }
36 | public Set getSectionItems(String name){
37 | return sections.get(name);
38 | }
39 | public void addSection(String name, Collection entityNames){
40 | sections.put(name, new HashSet(entityNames));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/fgd/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Classes to parse FGD (Forge Game Data) files which are used in the Source SDK.
4 |
5 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/GameInfoReader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 | import com.technofovea.hl2parse.JxPathUtil;
16 | import java.io.File;
17 | import java.util.ArrayList;
18 | import java.util.Iterator;
19 | import java.util.List;
20 | import org.apache.commons.jxpath.JXPathContext;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 |
24 | /**
25 | *
26 | * @author Darien Hager
27 | */
28 | public class GameInfoReader {
29 |
30 | public static final String PLACEHOLDER_ALLSOURCE = "all_source_engine_paths"; // Relative to main appid OR additional ones
31 | public static final String PLACEHOLDER_GAMEINFODIR = "gameinfo_path"; // Relative to gameinfo file's parent directory
32 | public static final String PATH_DELIM = "|"; // Marks beginning and end of placeholders
33 | public static final String DEFAULT_FILENAME = "gameinfo.txt";
34 |
35 | private static final Logger logger = LoggerFactory.getLogger(GameInfoReader.class);
36 | VdfRoot root;
37 | JXPathContext context;
38 | File sourceFile;
39 |
40 | public GameInfoReader(VdfRoot rootNode, File sourceFile) {
41 | this.sourceFile = sourceFile;
42 | root = rootNode;
43 | context = JXPathContext.newContext(root);
44 | JxPathUtil.addFunctions(context);
45 |
46 | }
47 |
48 | /**
49 | * Retrieves the path to the souce file. This is relevant since some paths
50 | * within the data are relative to the location of the file itself.
51 | * @return The File which was parsed. Potentially null, depending on usage.
52 | */
53 | public File getSourceFile() {
54 | return sourceFile;
55 | }
56 |
57 | public String getGameName() {
58 | return (String) context.getValue("children[custom:equals(name,'GameInfo')]/attributes[custom:equals(name,'game')]/value");
59 | }
60 |
61 | public int getSteamAppId() {
62 | String id = (String) context.getValue("children[custom:equals(name,'GameInfo')]/children[custom:equals(name,'FileSystem')]/attributes[custom:equals(name,'SteamAppId')]/value");
63 | return Integer.parseInt(id);
64 | }
65 |
66 | public List getSearchPaths() {
67 | List ret = new ArrayList();
68 | Iterator iter = (Iterator) context.iterate("children[custom:equals(name,'GameInfo')]/children[custom:equals(name,'FileSystem')]/children[custom:equals(name,'SearchPaths')]/attributes[custom:equals(name,'game')]/value");
69 | while (iter.hasNext()) {
70 | ret.add(iter.next());
71 | }
72 | return ret;
73 | }
74 | /*
75 | static List dereferenceSearchPaths(List paths, File gameInfoDirectory, File appIdDirectory ){
76 |
77 | }
78 | */
79 |
80 | public List getAdditionalIds() {
81 | List ret = new ArrayList();
82 | Iterator iter = (Iterator) context.iterate("children[custom:equals(name,'GameInfo')]/children[custom:equals(name,'FileSystem')]/attributes[custom:equals(name,'AdditionalContentId')]/value");
83 | while (iter.hasNext()) {
84 | ret.add(Integer.parseInt(iter.next()));
85 | }
86 | return ret;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/MaterialReader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 | import com.technofovea.hl2parse.*;
16 | import com.technofovea.hl2parse.xml.MaterialRefList;
17 | import com.technofovea.hl2parse.xml.MaterialReference;
18 | import java.io.InputStream;
19 | import java.util.HashSet;
20 | import java.util.Iterator;
21 | import java.util.Set;
22 | import javax.xml.bind.JAXBContext;
23 | import javax.xml.bind.JAXBException;
24 | import javax.xml.bind.Marshaller;
25 | import javax.xml.bind.Unmarshaller;
26 | import org.apache.commons.jxpath.JXPathContext;
27 | import org.slf4j.Logger;
28 | import org.slf4j.LoggerFactory;
29 |
30 | /**
31 | *
32 | * @author Darien Hager
33 | */
34 | public class MaterialReader {
35 |
36 | public static final MaterialRefList getDefaultMaterialSettings() throws JAXBException {
37 | InputStream is = MaterialReader.class.getResourceAsStream("DefaultMaterials.xml");
38 | return loadFromXml(is);
39 | }
40 |
41 | public static final MaterialRefList loadFromXml(InputStream stream) throws JAXBException {
42 | JAXBContext jc = JAXBContext.newInstance(MaterialReference.class, MaterialRefList.class);
43 | Unmarshaller um = jc.createUnmarshaller();
44 | Marshaller m = jc.createMarshaller();
45 | m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
46 |
47 | Object o = um.unmarshal(stream);
48 | return (MaterialRefList) o;
49 | }
50 | private static final Logger logger = LoggerFactory.getLogger(MaterialReader.class);
51 | static final String PATCH_INCLUDE = "include";
52 | VdfRoot root;
53 | JXPathContext context;
54 | MaterialRefList props;
55 | Set textures = new HashSet();
56 | Set materials = new HashSet();
57 |
58 | public MaterialReader(VdfRoot rootNode, MaterialRefList props) {
59 | root = rootNode;
60 | context = JXPathContext.newContext(root);
61 | JxPathUtil.addFunctions(context);
62 |
63 |
64 | Iterator allAttribs = context.iterate("//attributes");
65 |
66 | while (allAttribs.hasNext()) {
67 | VdfAttribute attrPair = allAttribs.next();
68 | String key = attrPair.getName();
69 | // Strip trailing "2"s for blend texture variations
70 | if (key.endsWith("2")) {
71 | logger.trace("Found 2-suffixed attribute variation: {}", key);
72 | key = key.substring(0, key.length() - 1);
73 | }
74 |
75 |
76 | if (key.equalsIgnoreCase(PATCH_INCLUDE)) {
77 | // According to docs, the patch shader's "include" directive
78 | // required a complete path with extension, ex.
79 | // materials/foo/bar.vmt
80 | // So we don't prefix or suffix this one
81 | logger.trace("Found possible patch-include shader material: {}", key);
82 |
83 | materials.add(attrPair.getValue());
84 | }
85 |
86 | for (MaterialReference ref : props) {
87 | if (!ref.hasName(key)) { // Case insensitive
88 | continue;
89 | }
90 | String val = attrPair.getValue();
91 | if (ref.hasIgnoreValue(val)) { // Case sensitive
92 | continue;
93 | }
94 |
95 | switch (ref.getType()) {
96 | case MATERIAL:
97 | logger.trace("Found material: {}", val);
98 | if (!val.toLowerCase().endsWith(".vmt")) {
99 | val += ".vmt";
100 | }
101 | materials.add("materials/" + val);
102 | break;
103 | case TEXTURE:
104 | logger.trace("Found texture: {}", val);
105 | if (!val.toLowerCase().endsWith(".vtf")) {
106 | val += ".vtf";
107 | }
108 | textures.add("materials/" + val);
109 | break;
110 | }
111 | break; // Break loop
112 | }
113 | }
114 | }
115 |
116 | public Set getMaterials() {
117 | return new HashSet(materials);
118 | }
119 |
120 | public Set getTextures() {
121 | return new HashSet(textures);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/ParticleManifestReader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 |
16 | import com.technofovea.hl2parse.JxPathUtil;
17 | import java.util.ArrayList;
18 | import java.util.Iterator;
19 | import java.util.List;
20 | import org.apache.commons.jxpath.JXPathContext;
21 |
22 | /**
23 | *
24 | * @author Darien Hager
25 | */
26 | public class ParticleManifestReader {
27 |
28 |
29 | private static final String CACHE_MARK = "!";
30 | private static final String KEY_NAME = "file";
31 | private VdfRoot root;
32 | private JXPathContext context;
33 |
34 | public ParticleManifestReader(VdfRoot rootNode) {
35 | root = rootNode;
36 | context = JXPathContext.newContext(root);
37 | JxPathUtil.addFunctions(context);
38 |
39 | context.getVariables().declareVariable("filekey", KEY_NAME);
40 | }
41 |
42 | public List getPcfs() {
43 | Iterator scapes = context.iterate("children[1]/attributes[custom:equals(name,$filekey)]/value");
44 | List ret = new ArrayList();
45 | while (scapes.hasNext()) {
46 | String path = (String) scapes.next();
47 | if (path.startsWith(CACHE_MARK)) {
48 | path = path.substring(CACHE_MARK.length());
49 | }
50 | ret.add(path);
51 | }
52 | return ret;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/PropDataReader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 | import com.technofovea.hl2parse.JxPathUtil;
16 | import java.util.ArrayList;
17 | import java.util.HashSet;
18 | import java.util.Iterator;
19 | import java.util.List;
20 | import java.util.Set;
21 | import org.apache.commons.jxpath.JXPathContext;
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 |
25 | /**
26 | *
27 | * @author Darien Hager
28 | */
29 | public class PropDataReader {
30 |
31 | private static final Logger logger = LoggerFactory.getLogger(PropDataReader.class);
32 | VdfRoot root;
33 | JXPathContext context;
34 |
35 | public PropDataReader(VdfRoot rootNode) {
36 | root = rootNode;
37 | context = JXPathContext.newContext(root);
38 | JxPathUtil.addFunctions(context);
39 | }
40 |
41 | public List getRagdollModels() {
42 | Iterator allSnds = context.iterate("children[custom:equals(name,'break')]/attributes[custom:equals(name,'ragdoll')]/value");
43 |
44 | List ret = new ArrayList();
45 | while (allSnds.hasNext()) {
46 | String path = allSnds.next();
47 | ret.add("models/" + path + ".mdl");
48 | }
49 | return ret;
50 | }
51 |
52 | public List getRigidGibModels() {
53 | Iterator allSnds = context.iterate("children[custom:equals(name,'break')]/attributes[custom:equals(name,'model')]/value");
54 |
55 | List ret = new ArrayList();
56 | while (allSnds.hasNext()) {
57 | String path = allSnds.next();
58 | ret.add(path);
59 | }
60 | return ret;
61 | }
62 |
63 | public Set getAllGibs() {
64 | Set ret = new HashSet();
65 | ret.addAll(getRagdollModels());
66 | ret.addAll(getRigidGibModels());
67 | return ret;
68 |
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/SoundScapeReader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 |
16 | import com.technofovea.hl2parse.JxPathUtil;
17 | import java.util.ArrayList;
18 | import java.util.Iterator;
19 | import java.util.List;
20 | import org.apache.commons.jxpath.JXPathContext;
21 |
22 | /**
23 | *
24 | * @author Darien Hager
25 | */
26 | public class SoundScapeReader {
27 |
28 | private static final String KEY_WAV = "wave";
29 |
30 | private VdfNode root;
31 | private JXPathContext context;
32 | public SoundScapeReader(VdfRoot rootNode) {
33 | root = rootNode;
34 | context = JXPathContext.newContext(root);
35 | JxPathUtil.addFunctions(context);
36 | context.getVariables().declareVariable("wavkey",KEY_WAV);
37 | }
38 | public List getSoundFiles(){
39 | Iterator allSnds = context.iterate("//attributes[custom:equals(name,$wavkey)]/value");
40 |
41 | List ret = new ArrayList();
42 | while (allSnds.hasNext()) {
43 | String path = allSnds.next();
44 | ret.add("sound/"+path);
45 | }
46 | return ret;
47 | }
48 | public List getSoundscapeNames(){
49 | Iterator scapes = context.iterate("/children/name");
50 | List ret = new ArrayList();
51 | while (scapes.hasNext()) {
52 | ret.add((String) scapes.next());
53 | }
54 | return ret;
55 |
56 | }
57 |
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/SteamMetaReader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 | import com.technofovea.hl2parse.*;
16 | import com.technofovea.hl2parse.JxPathUtil;
17 | import com.technofovea.hl2parse.vdf.VdfAttribute;
18 | import com.technofovea.hl2parse.vdf.VdfRoot;
19 | import java.util.HashSet;
20 | import java.util.Iterator;
21 | import java.util.Set;
22 | import org.apache.commons.jxpath.JXPathContext;
23 |
24 | /**
25 | *
26 | * @author Darien Hager
27 | */
28 | public class SteamMetaReader {
29 |
30 | VdfRoot root;
31 | JXPathContext context;
32 |
33 |
34 |
35 | public SteamMetaReader(VdfRoot rootNode) {
36 | root = rootNode;
37 | context = JXPathContext.newContext(root);
38 | JxPathUtil.addFunctions(context);
39 |
40 |
41 | }
42 |
43 | public String getAutoLogon() {
44 | return (String) context.getValue("children[custom:equals(name,'SteamAppData')]/attributes[custom:equals(name,'AutoLoginUser')]/value");
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/VdfAttribute.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 | /**
16 | *
17 | * @author Darien Hager
18 | */
19 | public class VdfAttribute {
20 |
21 | private String name = "";
22 | private String value = "";
23 |
24 | VdfAttribute(String key, String value) {
25 |
26 | this.name = key;
27 | this.value = value;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return "{"+this.name+":"+this.value+"}";
33 | }
34 |
35 | public String getName() {
36 | return name;
37 | }
38 |
39 | public String getValue() {
40 | return value;
41 | }
42 |
43 | public void setName(String name) {
44 | this.name = name;
45 | }
46 |
47 | public void setValue(String value) {
48 | this.value = value;
49 | }
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/VdfNode.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | /**
19 | * Used for parsing Valve's various similarly-formatted files. For convenience, many
20 | * accessors on this class throw exceptions since calling them implicitly signifies
21 | * you expect the data to be arranged a certain way.
22 | *
23 | * @author Darien Hager
24 | */
25 | public class VdfNode {
26 |
27 | private String name = "";
28 | private List children = new ArrayList();
29 | private List attributes = new ArrayList();
30 |
31 | public VdfNode(){
32 | }
33 |
34 | //TODO custom equality? Deep equality?
35 |
36 |
37 |
38 | @Override
39 | public String toString() {
40 | return toString(0, false);
41 | }
42 |
43 | public String toPrettyString() {
44 | return toString(0, true);
45 | }
46 |
47 | protected String toString(int indentLevel, boolean pretty) {
48 | StringBuilder sb = new StringBuilder();
49 |
50 | StringBuilder tabs = new StringBuilder();
51 | for (int i = 0; i < indentLevel; i++) {
52 | tabs.append("\t");
53 | }
54 | if (hasName()) {
55 | sb.append(tabs);
56 | sb.append("\"");
57 | sb.append(getName());
58 | sb.append("\"");
59 | sb.append("\n");
60 | }
61 | sb.append(tabs);
62 | sb.append("{\n");
63 |
64 | int maxKeyLen = 0;
65 | if (pretty) {
66 | // Pad everything so the key/value pairs are easy to read, so we
67 | // need a first pass to calculate lengths
68 | for (VdfAttribute att : attributes) {
69 | if (att.getName().length() > maxKeyLen) {
70 | maxKeyLen = att.getName().length();
71 | }
72 | }
73 | }
74 | for (VdfAttribute att : attributes) {
75 |
76 | sb.append(tabs);
77 | sb.append("\t");
78 | sb.append("\"");
79 | sb.append(att.getName());
80 | sb.append("\"");
81 | if (pretty) {
82 | sb.append(" ");
83 | for (int i = 0; i < maxKeyLen - att.getName().length(); i++) {
84 | sb.append(" ");
85 | }
86 | } else {
87 | sb.append(" ");
88 | }
89 | sb.append("\"");
90 | sb.append(att.getValue());
91 | sb.append("\"");
92 |
93 | sb.append("\n");
94 |
95 | }
96 | for (VdfNode vn : children) {
97 | String childString = vn.toString(indentLevel + 1, pretty);
98 | sb.append(childString);
99 | }
100 | sb.append(tabs);
101 | sb.append("}\n");
102 | return sb.toString();
103 | }
104 |
105 | public boolean addChild(VdfNode n) {
106 | if (n == this) {
107 | return false;
108 | }
109 | return children.add(n);
110 | }
111 |
112 | public void addAttribute(String key, String value) {
113 | VdfAttribute va = new VdfAttribute(key, value);
114 | attributes.add(va);
115 | return;
116 | }
117 |
118 | public void setName(String s) {
119 | name = s;
120 | }
121 |
122 | public List getChildren() {
123 | return children;
124 | }
125 |
126 | public boolean hasName() {
127 | return (name != null);
128 | }
129 |
130 | public String getName() {
131 | if (name == null) {
132 | return "";
133 | }
134 | return name;
135 | }
136 |
137 | public List getAttributes() {
138 | return attributes;
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/VdfRoot.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.vdf;
14 |
15 | /**
16 | *
17 | * @author Darien Hager
18 | */
19 | public class VdfRoot extends VdfNode{
20 |
21 | @Override
22 | public String toString(int indentLevel, boolean pretty) {
23 | StringBuilder sb = new StringBuilder();
24 |
25 | for(VdfNode vn : getChildren()){
26 | sb.append(vn.toString(indentLevel,pretty));
27 | }
28 | return sb.toString();
29 | }
30 |
31 | @Override
32 | public boolean hasName() {
33 | return false;
34 | }
35 |
36 | @Override
37 | public String getName() {
38 | return "";
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/vdf/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Classes for parsing and traversing "Valve Data Format" files, a type of
4 | hierarchical data commonly used by the Source engine.
5 |
6 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/xml/MaterialRefList.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.xml;
14 |
15 | import java.util.ArrayList;
16 | import java.util.Iterator;
17 | import java.util.List;
18 | import java.util.ListIterator;
19 | import javax.xml.bind.annotation.XmlAccessType;
20 | import javax.xml.bind.annotation.XmlAccessorType;
21 | import javax.xml.bind.annotation.XmlElement;
22 | import javax.xml.bind.annotation.XmlRootElement;
23 |
24 | /**
25 | *
26 | * @author Darien Hager
27 | */
28 | @XmlRootElement
29 | @XmlAccessorType(XmlAccessType.NONE)
30 | public class MaterialRefList implements Iterable{
31 |
32 | @XmlElement(required=true,name="item")
33 | protected List items = new ArrayList();
34 |
35 | public List getItems() {
36 | return items;
37 | }
38 |
39 | public void setItems(List items) {
40 | this.items = items;
41 | }
42 |
43 | public int size() {
44 | return items.size();
45 | }
46 |
47 | public MaterialReference remove(int index) {
48 | return items.remove(index);
49 | }
50 |
51 | public Iterator iterator() {
52 | return items.iterator();
53 | }
54 |
55 | public MaterialReference get(int index) {
56 | return items.get(index);
57 | }
58 |
59 | public boolean contains(MaterialReference o) {
60 | return items.contains(o);
61 | }
62 |
63 | public void clear() {
64 | items.clear();
65 | }
66 |
67 | public boolean add(MaterialReference e) {
68 | return items.add(e);
69 | }
70 |
71 | public String toString() {
72 | return items.toString();
73 | }
74 |
75 | public ListIterator listIterator(int index) {
76 | return items.listIterator(index);
77 | }
78 |
79 | public ListIterator listIterator() {
80 | return items.listIterator();
81 | }
82 |
83 |
84 |
85 |
86 |
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/java/com/technofovea/hl2parse/xml/MaterialReference.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.xml;
14 |
15 | import java.util.HashSet;
16 | import java.util.Set;
17 | import javax.xml.bind.annotation.XmlAccessType;
18 | import javax.xml.bind.annotation.XmlAccessorType;
19 | import javax.xml.bind.annotation.XmlElement;
20 | import javax.xml.bind.annotation.XmlEnum;
21 | import javax.xml.bind.annotation.XmlEnumValue;
22 | import javax.xml.bind.annotation.XmlList;
23 | import javax.xml.bind.annotation.XmlType;
24 |
25 | /**
26 | * Represents a material property that references another asset. For example,
27 | * $basetexture references an external texture.
28 | * @author Darien Hager
29 | */
30 | @XmlAccessorType(XmlAccessType.NONE)
31 | public class MaterialReference {
32 |
33 | @XmlType
34 | @XmlEnum(value = String.class)
35 | public static enum ReferenceType {
36 |
37 | @XmlEnumValue("texture")
38 | TEXTURE,
39 |
40 | @XmlEnumValue("material")
41 | MATERIAL
42 | }
43 |
44 |
45 | @XmlElement(required = true)
46 | @XmlList // Allows whitespace-separation
47 | protected Set names = new HashSet();;
48 | @XmlElement(required = false,name="ignoreValue")
49 | protected Set ignoreValues = new HashSet();
50 | @XmlElement(required = false, defaultValue="texture")
51 | protected ReferenceType type = ReferenceType.TEXTURE;
52 |
53 | public Set getIgnoreValues() {
54 | return ignoreValues;
55 | }
56 |
57 | public void setIgnoreValues(Set ignoreValues) {
58 | this.ignoreValues = ignoreValues;
59 | }
60 |
61 | public Set getNames() {
62 | return names;
63 | }
64 |
65 | public void setNames(Set names) {
66 | this.names = new HashSet();
67 | for(String n: names){
68 | this.names.add(n.toLowerCase());
69 | }
70 | }
71 |
72 | public ReferenceType getType() {
73 | return type;
74 | }
75 |
76 | public void setType(ReferenceType type) {
77 | this.type = type;
78 | }
79 |
80 | public void addName(String name){
81 | names.add(name.toLowerCase());
82 | }
83 |
84 | public void addIgnoreValue(String val){
85 | ignoreValues.add(val);
86 | }
87 |
88 | public boolean hasName(String name){
89 | return names.contains(name.toLowerCase());
90 | }
91 |
92 | public boolean hasIgnoreValue(String val){
93 | return ignoreValues.contains(val);
94 | }
95 |
96 | @Override
97 | public boolean equals(Object obj) {
98 | if (obj == null) {
99 | return false;
100 | }
101 | if (getClass() != obj.getClass()) {
102 | return false;
103 | }
104 | final MaterialReference other = (MaterialReference) obj;
105 | if (this.names != other.names && (this.names == null || !this.names.equals(other.names))) {
106 | return false;
107 | }
108 | if (this.ignoreValues != other.ignoreValues && (this.ignoreValues == null || !this.ignoreValues.equals(other.ignoreValues))) {
109 | return false;
110 | }
111 | if (this.type != other.type && (this.type == null || !this.type.equals(other.type))) {
112 | return false;
113 | }
114 | return true;
115 | }
116 |
117 | @Override
118 | public int hashCode() {
119 | int hash = 7;
120 | hash = 97 * hash + (this.names != null ? this.names.hashCode() : 0);
121 | hash = 97 * hash + (this.ignoreValues != null ? this.ignoreValues.hashCode() : 0);
122 | hash = 97 * hash + (this.type != null ? this.type.hashCode() : 0);
123 | return hash;
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/hl2parse-common/src/main/resources/com/technofovea/hl2parse/vdf/DefaultMaterials.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 | -
11 | $basetexture
12 | texture
13 |
14 | -
15 | $bumpmap
16 |
17 | -
18 | $normalmap
19 |
20 | -
21 | $detail
22 |
23 | -
24 | $dudvmap
25 |
26 | -
27 | $refracttinttexture
28 |
29 | -
30 | $envmapmask
31 |
32 | -
33 | $parallaxmap
34 |
35 | -
36 | $ambientoccltexture
37 |
38 | -
39 | $hdrcompressedtexture $hdrbasetexture
40 |
41 | -
42 | $lightwarptexture
43 |
44 | -
45 | $refracttinttexture
46 |
47 | -
48 | $phongexponenttexture
49 |
50 | -
51 | $fallbackmaterial
52 | material
53 |
54 | -
55 | $bottommaterial
56 | material
57 |
58 | -
59 | $underwateroverlay
60 | material
61 |
62 | -
63 | $refracttexture
64 | _rt_WaterRefraction
65 | texture
66 |
67 | -
68 | $envmap
69 | env_cubemap
70 | texture
71 |
72 | -
73 | $reflecttexture
74 | _rt_WaterReflection
75 | texture
76 |
77 | -
78 | $fallbackmaterial
79 | material
80 |
81 |
82 |
83 |
84 | -
85 | $FleshInteriorTexture
86 | $FleshNormalTexture
87 | $FleshBorderTexture1D
88 | $FleshInteriorNoiseTexture
89 | $FleshSubsurfaceTexture
90 |
91 | -
92 | $FleshCubeTexture
93 | env_cubemap
94 | material
95 |
96 |
--------------------------------------------------------------------------------
/hl2parse-common/src/test/resources/log4j.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/hl2parse-parsers/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | com.technofovea
7 | hl2parse
8 | 1.2.2-SNAPSHOT
9 |
10 |
11 | hl2parse-parsers
12 | hl2parse-parsers
13 |
14 |
15 |
16 |
17 | org.antlr
18 | antlr3-maven-plugin
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | com.technofovea
28 | hl2parse-common
29 |
30 |
31 |
32 | org.antlr
33 | antlr-runtime
34 |
35 |
36 |
37 | junit
38 | junit
39 | test
40 |
41 |
42 |
43 | org.slf4j
44 | slf4j-api
45 |
46 |
47 | org.slf4j
48 | slf4j-log4j12
49 |
50 |
51 |
52 |
53 |
54 | ${basedir}/..
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/hl2parse-parsers/src/main/antlr3/com/technofovea/hl2parse/vdf/SloppyParser.g:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | parser grammar SloppyParser;
14 | options{
15 | tokenVocab=ValveTokenLexer;
16 | }
17 |
18 |
19 | @header {
20 | package com.technofovea.hl2parse.vdf;
21 | import com.technofovea.hl2parse.ParserException;
22 |
23 | /*
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 | */
27 | }
28 | @rulecatch {
29 | catch (RecognitionException ex) {
30 | // Instead of printing out error messages, just exit early with an exception.
31 | if(ex instanceof ParserException){
32 | throw(ex);
33 | }
34 | ParserException carrier = new ParserException(this,ex);
35 | throw carrier;
36 | }
37 | }
38 |
39 | main returns [VdfRoot root]
40 | @init{
41 | root = new VdfRoot();
42 | }
43 | : WS* block[root] (WS* block[root])* WS*
44 | ;
45 |
46 | item[VdfNode parent]
47 | : block[parent]
48 | | scalar[parent]
49 | ;
50 |
51 | block[VdfNode parent]
52 | @init{
53 | VdfNode current = new VdfNode();
54 | }
55 | : (bn=blockName WS?)? LBRACE WS* (item[current] (WS+ item[current])* WS*)? RBRACE
56 | {
57 | current.setName($bn.text);
58 | parent.addChild(current);
59 | }
60 | ;
61 |
62 | blockName
63 | : (STRING)=> STRING
64 | | unquotedMess
65 | ;
66 | scalar[VdfNode parent]
67 | : (STRING STRING)=> nt=STRING vt=STRING
68 | {
69 | parent.addAttribute($nt.text,$vt.text);
70 | }
71 | | n=scalarName WS+ v=scalarVal
72 | {
73 | parent.addAttribute($n.text,$v.text);
74 | }
75 | ;
76 | scalarName
77 | : (STRING)=> STRING
78 | | unquotedMess
79 | ;
80 | scalarVal
81 | : (STRING)=> STRING
82 | | unquotedMess
83 | ;
84 |
85 | unquotedMess
86 | : (~(STRING|QUOT|COLON|EQUALS|LSQUARE|RSQUARE|LPAREN|RPAREN|LBRACE|RBRACE|WS|COMMENT))+
87 | ;
88 |
89 |
90 |
--------------------------------------------------------------------------------
/hl2parse-parsers/src/main/antlr3/com/technofovea/hl2parse/vdf/ValveTokenLexer.g:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | lexer grammar ValveTokenLexer;
14 |
15 | @header {
16 | package com.technofovea.hl2parse.vdf;
17 | import com.technofovea.hl2parse.ParserException;
18 |
19 | /*
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 | */
23 | }
24 |
25 |
26 |
27 |
28 | @members{
29 |
30 | public boolean mismatchIsUnwantedToken(IntStream input, int ttype) {
31 | // Disable error-recovery method
32 | return false;
33 | }
34 |
35 | public boolean mismatchIsMissingToken(IntStream input, BitSet follow) {
36 | // Disable error-recovery method
37 | return false;
38 | }
39 | }
40 |
41 | AT : '@';
42 | COMMA : ',';
43 | EXCL : '!';
44 | PLUS : '+';
45 | AMPERSAND : '&';
46 | STAR : '*';
47 | DOLLAR : '$';
48 | EQUALS : '=';
49 | COLON : ':';
50 | LSQUARE : '[';
51 | RSQUARE : ']';
52 | LPAREN : '(';
53 | RPAREN : ')';
54 | LBRACE : '{';
55 | RBRACE : '}';
56 | BSLASH : '\\';
57 | PERCENT : '%';
58 | LESSER : '<';
59 | GREATER : '>';
60 | PIPE : '|';
61 | SLASH : '/';
62 | NULL : '\u0000';
63 |
64 | fragment DIGIT : '0'..'9';
65 | fragment ALPHA : 'a'..'z'|'A'..'Z';
66 | fragment UNDERSCORE : '_';
67 | fragment QUOT : '"';
68 |
69 |
70 | IDENT : (ALPHA|UNDERSCORE)(ALPHA|DIGIT|UNDERSCORE)*
71 | ;
72 |
73 | FLOAT : DOT DIGIT+
74 | | INT DOT DIGIT+
75 | ;
76 |
77 | INT : MINUS? DIGIT+ ;
78 |
79 |
80 | MINUS : '-';
81 | DOT : '.';
82 |
83 | STRING
84 | : QUOT ( ~QUOT | '\\"')* QUOT
85 | {
86 | setText(getText().substring(1, getText().length()-1));
87 | }
88 | ;
89 |
90 | fragment CRETURN : '\r';
91 | fragment NLINE : '\n';
92 | fragment SPACE : ' ';
93 | fragment TAB : '\t';
94 |
95 | COMMENT
96 | : '//' ~(CRETURN|NLINE)* (CRETURN|NLINE|EOF) {$channel=HIDDEN;}
97 | ;
98 |
99 |
100 |
101 | WS : (SPACE|TAB|CRETURN|NLINE)+
102 | ;
103 |
104 |
105 | /*
106 | Note that @rulecatch does nothing in the lexer, recommended way is to create
107 | a final "bad" rule to do things.
108 | See http://www.mail-archive.com/il-antlr-interest@googlegroups.com/msg02132.html
109 |
110 |
111 | BADINPUT : . { System.err.println("The character '" + $text + "' is not a legal character in this language or something."); } ;
112 |
113 |
114 | //ParserException carrier = new ParserException(this,ex);
115 | //throw carrier;
116 | */
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/hl2parse-parsers/src/main/java/com/technofovea/hl2parse/ParserException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse;
14 |
15 |
16 |
17 |
18 | import org.antlr.runtime.BaseRecognizer;
19 | import org.antlr.runtime.RecognitionException;
20 |
21 | /**
22 | * Used by text parsers to indicate that an error has occurred while parsing
23 | * text data files.
24 | * @author Darien Hager
25 | */
26 | public class ParserException extends RecognitionException {
27 |
28 | String header;
29 | String message;
30 | RecognitionException cause;
31 | public ParserException(BaseRecognizer parser, RecognitionException cause) {
32 | super(cause.input);
33 | // Parent class doesn't do causes!
34 | initCause(cause);
35 |
36 | header = parser.getErrorHeader(cause);
37 | message = parser.getErrorMessage(cause, parser.getTokenNames());
38 | }
39 |
40 | @Override
41 | public String getMessage() {
42 | return header+": "+message;
43 | }
44 |
45 | @Override
46 | public String toString() {
47 | return getClass().getSimpleName()+": "+getMessage();
48 | }
49 | /*
50 | @Override
51 | public Throwable getCause() {
52 | return cause;
53 | }
54 | */
55 |
56 |
57 |
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/hl2parse-parsers/src/main/java/com/technofovea/hl2parse/fgd/DefaultLoader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | import java.io.File;
16 | import java.io.FileInputStream;
17 | import java.io.IOException;
18 | import java.util.ArrayList;
19 | import java.util.List;
20 | import org.antlr.runtime.ANTLRInputStream;
21 | import org.antlr.runtime.CharStream;
22 | import org.antlr.runtime.CommonTokenStream;
23 | import org.antlr.runtime.RecognitionException;
24 |
25 | /**
26 | *
27 | * @author Darien Hager
28 | */
29 | public class DefaultLoader implements FgdLoader {
30 |
31 | List history = new ArrayList();
32 | File workingDir = null;
33 |
34 | public static FgdLoader fillSpec(File target, FgdSpec spec) throws IOException, RecognitionException{
35 | FgdLoader ldr = new DefaultLoader();
36 | CharStream stream = ldr.getStream(target.getAbsolutePath());
37 | ForgeGameDataLexer lexer = new ForgeGameDataLexer(stream);
38 | ForgeGameDataParser parser = new ForgeGameDataParser(new CommonTokenStream(lexer));
39 | parser.main(spec, ldr);
40 | return ldr;
41 | }
42 |
43 |
44 | public DefaultLoader() {
45 | }
46 |
47 | public CharStream getStream(String path) throws IOException {
48 | File target;
49 | if (workingDir == null) {
50 | target = new File(path);
51 | } else {
52 | target = new File(workingDir, path);
53 | }
54 | if (history.contains(target)) {
55 | throw new IOException("Cyclic include detected with target: " + path);
56 | }
57 |
58 | ANTLRInputStream ais = new ANTLRInputStream(new FileInputStream(target));
59 |
60 | if(workingDir == null){
61 | workingDir = target.getParentFile();
62 | }
63 | history.add(target);
64 | return ais;
65 | }
66 |
67 | public void reset() {
68 | history.clear();
69 | workingDir = null;
70 | }
71 | /*
72 | public void loadFrom(File fgd) throws IOException, RecognitionException {
73 | loadFrom(fgd, new ArrayList());
74 | }
75 |
76 | public void loadFrom(File fgd, List history) throws IOException, RecognitionException {
77 | if (history.contains(fgd)) {
78 | // Cyclic importing detected. We don't want an infinite loop, so...
79 | throw new IOException("Cyclic include directives detected.");
80 | }
81 | history.add(fgd);
82 | ANTLRInputStream ais = new ANTLRInputStream(new FileInputStream(fgd));
83 | ForgeGameDataLexer lexer = new ForgeGameDataLexer(ais);
84 | ForgeGameDataParser parser = new ForgeGameDataParser(new CommonTokenStream(lexer));
85 | parser.main(fgd, this, history);
86 | }
87 | *
88 | */
89 | }
90 |
--------------------------------------------------------------------------------
/hl2parse-parsers/src/main/java/com/technofovea/hl2parse/fgd/FgdLoader.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | import java.io.IOException;
16 | import org.antlr.runtime.CharStream;
17 |
18 | /**
19 | * Since FGDs can import one-another from relative paths, a loader is responsible
20 | * for maintaining the correct context, resolving those paths, loading the data,
21 | * and guarding against cyclic dependencies.
22 | *
23 | * @author Darien Hager
24 | */
25 | public interface FgdLoader {
26 |
27 | public void reset();
28 |
29 | public CharStream getStream(String path) throws IOException;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/hl2parse-tests/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | com.technofovea
7 | hl2parse
8 | 1.2.2-SNAPSHOT
9 |
10 |
11 | hl2parse-tests
12 | hl2parse-tests
13 |
14 |
15 |
16 |
17 |
18 |
19 | com.technofovea
20 | hl2parse-common
21 |
22 |
23 | com.technofovea
24 | hl2parse-parsers
25 |
26 |
27 | com.technofovea
28 | hl2parse-binary
29 |
30 |
31 |
32 | org.slf4j
33 | slf4j-api
34 |
35 |
36 | org.slf4j
37 | slf4j-log4j12
38 |
39 |
40 |
41 | junit
42 | junit
43 | test
44 |
45 |
46 |
47 |
48 |
49 |
50 | ${basedir}/..
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/java/com/technofovea/hl2parse/bsp/BspParseTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.bsp;
14 |
15 | import com.technofovea.hl2parse.bsp.SourceMapAnalyzer;
16 | import com.technofovea.hl2parse.ParseUtil;
17 | import java.io.File;
18 | import java.io.FileReader;
19 | import java.io.LineNumberReader;
20 | import java.nio.ByteBuffer;
21 | import java.util.Enumeration;
22 | import java.util.HashSet;
23 | import java.util.Map;
24 | import java.util.Set;
25 | import java.util.zip.ZipEntry;
26 | import java.util.zip.ZipFile;
27 | import org.junit.Assert;
28 | import org.junit.Test;
29 |
30 | /**
31 | *
32 | * @author Darien
33 | */
34 | public class BspParseTest {
35 |
36 | static final String BSP_LOC = "test_bsp_parse.bsp";
37 | //static final String BSP_LOC = "../sdk_ctf_2fort.bsp";
38 |
39 | @Test
40 | public void testBspParsing() throws Exception {
41 | ByteBuffer bb = ParseUtil.mapFile(new File(this.getClass().getResource(BSP_LOC).toURI()));
42 |
43 | SourceMapAnalyzer sma = new SourceMapAnalyzer(bb);
44 |
45 | Set expectedMaterials = new HashSet();
46 | expectedMaterials.add("materials/BRICK/BRICKFLOOR001A");
47 | expectedMaterials.add("materials/STONE/STONEWALL006B");
48 | expectedMaterials.add("materials/STONE/STONEWALL033A");
49 | expectedMaterials.add("materials/PLASTER/PLASTERCEILING003A");
50 |
51 | // Two decals
52 | expectedMaterials.add("materials/wood/wooddoor008a");
53 | expectedMaterials.add("materials/decals/decalgraffiti003a");
54 |
55 | /*//Tool textures
56 | expectedMaterials.add("materials/TOOLS/TOOLSTRIGGER");
57 | expectedMaterials.add("materials/TOOLS/TOOLSSKYBOX");
58 | */
59 |
60 | /*//Cubemaps
61 | expectedMaterials.add("materials/maps/test_bsp_parse/tile/tilefloor001b_0_0_-896");
62 | expectedMaterials.add("materials/maps/test_bsp_parse/tile/tilefloor001b_352_352_-896");
63 | expectedMaterials.add("materials/maps/test_bsp_parse/tile/tilefloor009b_0_0_-896");
64 | expectedMaterials.add("materials/maps/test_bsp_parse/stone/stonestair001a_0_0_-896");
65 | */
66 |
67 |
68 | Set foundTextures = new HashSet();
69 | for (String found : sma.getBrushTextures()) {
70 | foundTextures.add(found.toLowerCase());
71 | }
72 | for (String expected : expectedMaterials) {
73 | expected = expected.toLowerCase();
74 | Assert.assertTrue(expected, foundTextures.contains(expected));
75 | }
76 |
77 | Map> foundStaticProps = sma.getStaticPropSkins();
78 |
79 | Assert.assertTrue(foundStaticProps.get("models/props_trainstation/bench_indoor001a.mdl").contains(0));
80 | Assert.assertTrue(foundStaticProps.get("models/props_trainstation/column_light001b.mdl").contains(1));
81 | Assert.assertTrue(foundStaticProps.get("models/props_trainstation/trashcan_indoor001a.mdl").contains(0));
82 | Assert.assertTrue(foundStaticProps.get("models/props_trainstation/payphone001a.mdl").contains(0));
83 |
84 | }
85 |
86 | /*
87 | @Test
88 | public void testEntdataParsing() throws Exception {
89 | ByteBuffer bb = ParseUtil.mapFile(new File(this.getClass().getResource(BSP_LOC).toURI()));
90 |
91 | SourceMapAnalyzer sma = new SourceMapAnalyzer(bb);
92 |
93 | String entData = sma.getEntData();
94 | VdfParser vfp = new VdfParser(entData);
95 | VdfNode n = vfp.go();
96 | MapEntityData med = new MapEntityData(n);
97 |
98 | Set foundDynamicModels = med.getDynamicModels();
99 | Set expectedDynamicModels = new HashSet();
100 |
101 | expectedDynamicModels.add("models/props_borealis/bluebarrel001.mdl");
102 |
103 | for (String expected : expectedDynamicModels) {
104 | Assert.assertTrue(expected, foundDynamicModels.contains(expected));
105 | }
106 | }
107 | */
108 | @Test
109 | public void testPackedFiles() throws Exception {
110 | ByteBuffer bb = ParseUtil.mapFile(new File(this.getClass().getResource(BSP_LOC).toURI()));
111 |
112 | SourceMapAnalyzer sma = new SourceMapAnalyzer(bb);
113 |
114 | Set packedFilePaths = new HashSet();
115 | ZipFile zf = sma.getPackedFiles();
116 | Enumeration extends ZipEntry> en = zf.entries();
117 | while (en.hasMoreElements()) {
118 | ZipEntry entry = en.nextElement();
119 | packedFilePaths.add(entry.getName());
120 | //System.out.println(entry.getName());
121 | }
122 |
123 | Assert.assertTrue(packedFilePaths.contains("materials/maps/test_bsp_parse/cubemapdefault.vtf"));
124 |
125 | if (false) {
126 | File f = sma.getPackedFile("materials/maps/test_bsp_parse/tile/tilefloor001b_352_352_-896.vmt");
127 | FileReader fr = new FileReader(f);
128 | LineNumberReader lnr = new LineNumberReader(fr);
129 | String line = "";
130 | while(line != null){
131 | line = lnr.readLine();
132 | System.out.println(line);
133 | }
134 | sma.getPackedFile("materials/maps/test_bsp_parse/tile/tilefloor001b_352_352_-896.vmt");
135 | sma.getPackedFile("materials/maps/test_bsp_parse/tile/tilefloor001b_352_352_-896.vmt");
136 |
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/java/com/technofovea/hl2parse/entdata/EntityProcessingTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.entdata;
14 |
15 | import com.technofovea.hl2parse.fgd.DefaultLoader;
16 | import com.technofovea.hl2parse.fgd.FgdEntClass;
17 | import com.technofovea.hl2parse.fgd.FgdSpec;
18 | import com.technofovea.hl2parse.vdf.SloppyParser;
19 | import com.technofovea.hl2parse.vdf.ValveTokenLexer;
20 | import com.technofovea.hl2parse.vdf.VdfRoot;
21 | import java.io.File;
22 | import java.io.InputStream;
23 | import java.util.Collection;
24 | import java.util.HashSet;
25 | import java.util.List;
26 | import java.util.Set;
27 | import org.antlr.runtime.ANTLRInputStream;
28 | import org.antlr.runtime.CommonTokenStream;
29 | import org.junit.Assert;
30 | import org.junit.Test;
31 |
32 | /**
33 | *
34 | * @author Darien
35 | */
36 | public class EntityProcessingTest {
37 |
38 | private boolean checkContains(Collection c, String target) {
39 | boolean found = false;
40 | for (String s : c) {
41 | if (target.equalsIgnoreCase(s)) {
42 | return true;
43 | }
44 | }
45 | return false;
46 | }
47 |
48 | @Test
49 | public void temp() throws Exception {
50 |
51 | final String fgdPath = "tf.fgd";
52 | final String entPath = "ctf_2fort.ent";
53 |
54 |
55 | File srcFile = new File(getClass().getResource(fgdPath).toURI());
56 | InputStream entStream = getClass().getResourceAsStream(entPath);
57 | ValveTokenLexer vfp = new ValveTokenLexer(new ANTLRInputStream(entStream));
58 | SloppyParser sp = new SloppyParser(new CommonTokenStream(vfp));
59 | VdfRoot entRoot = sp.main();
60 | List ents = MapEntity.fromVdf(entRoot);
61 |
62 | FgdSpec spec = new FgdSpec();
63 | DefaultLoader.fillSpec(srcFile,spec);
64 |
65 | System.out.println(spec.toText());
66 |
67 | final String entName = "func_respawnroom";
68 | FgdEntClass spawnroom = spec.getEntClass(entName); // Get normal version
69 | Assert.assertNotNull(spawnroom);
70 | System.out.println(spawnroom.toText(entName)); // Print sparse form
71 | FgdEntClass combined = spawnroom.getInherited(spec); // Do inheritance
72 | System.out.println(combined.toText(entName)); // Print combined form
73 |
74 |
75 | DependencyFinder df = new DependencyFinder(spec, ents, DefaultPathFixer.getInstance());
76 |
77 |
78 | Set sounds = new HashSet();
79 | for (ValueSource ep : df.getPropertiesByType(DependencyFinder.PROPTYPE_SOUND)) {
80 | sounds.addAll(df.getValues(ep));
81 | }
82 | Assert.assertTrue(sounds.contains(":Ambient.MachineHum"));
83 |
84 | // Note that this test does NOT include prop_static entities, because
85 | // those are packaged differently into the BSP file.
86 | Set models = new HashSet();
87 | for (ValueSource ep : df.getPropertiesByType(DependencyFinder.PROPTYPE_MODEL)) {
88 | models.addAll(df.getValues(ep));
89 | }
90 | Assert.assertTrue(models.contains("models/props_gameplay/resupply_locker.mdl"));
91 | Assert.assertTrue(models.contains("models/props_skybox/sunnoon.mdl"));
92 |
93 | Set decals = new HashSet();
94 | for (ValueSource ep : df.getPropertiesByType(DependencyFinder.PROPTYPE_DECAL)) {
95 | decals.addAll(df.getValues(ep));
96 | }
97 | //TODO use some decals in our test file!
98 |
99 | Set sprites = new HashSet();
100 | for (ValueSource ep : df.getPropertiesByType(DependencyFinder.PROPTYPE_SPRITE)) {
101 | sprites.addAll(df.getValues(ep));
102 | }
103 | Assert.assertTrue(sprites.contains("materials/Sprites/light_glow03.vmt"));
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/java/com/technofovea/hl2parse/fgd/BaselineTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | import java.io.File;
16 | import java.net.URL;
17 | import org.apache.log4j.Level;
18 | import org.junit.Assert;
19 | import org.junit.Test;
20 |
21 | /**
22 | *
23 | * @author Darien Hager
24 | */
25 | public class BaselineTest {
26 |
27 | @Test
28 | public void test1() throws Exception {
29 | org.apache.log4j.Logger.getRootLogger().setLevel(Level.ALL);
30 |
31 | URL fileUrl = getClass().getResource("overall.fgd");
32 | File srcFile = new File(fileUrl.toURI());
33 | FgdSpec spec = new FgdSpec();
34 | DefaultLoader.fillSpec(srcFile,spec);
35 |
36 | System.out.println(spec.toText());
37 | // This test has no classes by design
38 | Assert.assertEquals(0,spec.getEntClassNames().size());
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/java/com/technofovea/hl2parse/fgd/CombinationTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.fgd;
14 |
15 | import java.io.File;
16 | import java.io.IOException;
17 | import java.net.URL;
18 | import java.util.Collections;
19 | import java.util.HashSet;
20 | import java.util.Map;
21 | import java.util.Set;
22 | import org.junit.Assert;
23 | import org.junit.Test;
24 | import static org.junit.Assert.*;
25 |
26 | /**
27 | *
28 | * @author Darien
29 | */
30 | public class CombinationTest {
31 |
32 | @Test
33 | public void testMultipleInheritance() throws Exception {
34 |
35 | URL fileUrl = getClass().getResource("inherit_test.fgd");
36 | File srcFile = new File(fileUrl.toURI());
37 | FgdSpec spec = new FgdSpec();
38 | DefaultLoader.fillSpec(srcFile,spec);
39 |
40 | //System.out.println(spec.toText());
41 | FgdEntClass combined = spec.getEntClass("CyberBird").getInherited(spec);
42 |
43 | Assert.assertEquals("PointClass", combined.getType());
44 | Set expectedProps = new HashSet();
45 | expectedProps.add("manufacturer");
46 | expectedProps.add("airating");
47 | expectedProps.add("engines");
48 | expectedProps.add("wingcount");
49 | expectedProps.add("maxheight");
50 | expectedProps.add("conflictingproperty");
51 | Assert.assertEquals(expectedProps, combined.getProps().keySet());
52 |
53 |
54 | // Test that our reference to a property is directly referring to an object
55 | // associated with a parent ent-class object.
56 | final Map machineProps = Collections.unmodifiableMap(spec.getEntClass("Machine").getProps());
57 |
58 | FgdProperty base = machineProps.get("manufacturer");
59 | FgdProperty inherited = combined.getProps().get("manufacturer");
60 | Assert.assertEquals(base, inherited);
61 |
62 | // Test that the inheritance order was correct
63 | FgdProperty expectedConflicter = machineProps.get("conflictingproperty");
64 | FgdProperty conflicter = combined.getProps().get("conflictingproperty");
65 | Assert.assertEquals(expectedConflicter, conflicter);
66 |
67 | }
68 |
69 | @Test
70 | public void testImporting() throws Exception {
71 |
72 | final String ALPHA = "Alpha";
73 | final String BETA = "Beta";
74 | final String DELTA = "Delta";
75 | final String EPSILON = "Epsilon";
76 | final String GAMMA = "Gamma";
77 |
78 | URL fileUrl = getClass().getResource("importer.fgd");
79 | File srcFile = new File(fileUrl.toURI());
80 | FgdSpec spec = new FgdSpec();
81 | DefaultLoader.fillSpec(srcFile,spec);
82 |
83 |
84 |
85 | Set expectedClasses = new HashSet();
86 | expectedClasses.add(ALPHA);
87 | expectedClasses.add(BETA);
88 | expectedClasses.add(GAMMA);
89 | expectedClasses.add(DELTA);
90 | expectedClasses.add(EPSILON);
91 |
92 | Assert.assertTrue(spec.getEntClassNames().containsAll(expectedClasses));
93 |
94 |
95 | // Test that our order-based erasing happened appropriately
96 | final Set deltaKeyset = spec.getEntClass(DELTA).getProps().keySet();
97 | final Set gammaKeyset = spec.getEntClass(EPSILON).getProps().keySet();
98 |
99 | Assert.assertTrue(deltaKeyset.contains("eraser"));
100 | Assert.assertFalse(deltaKeyset.contains("erased"));
101 | Assert.assertTrue(gammaKeyset.contains("eraser"));
102 | Assert.assertFalse(gammaKeyset.contains("erased"));
103 |
104 | }
105 |
106 | @Test(timeout = 5000)
107 | public void testCyclicImports() throws Exception {
108 | // Just make sure they don't fail horribly. They're certainly invalid.
109 | URL fileUrl = getClass().getResource("cyclic1.fgd");
110 | File srcFile = new File(fileUrl.toURI());
111 | FgdSpec spec = new FgdSpec();
112 | DefaultLoader.fillSpec(srcFile,spec);
113 |
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/java/com/technofovea/hl2parse/mdl/ModelDataTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.mdl;
14 |
15 | import com.technofovea.hl2parse.ParseUtil;
16 | import com.technofovea.hl2parse.vdf.PropDataReader;
17 | import com.technofovea.hl2parse.vdf.SloppyParser;
18 | import com.technofovea.hl2parse.vdf.ValveTokenLexer;
19 | import com.technofovea.hl2parse.vdf.VdfRoot;
20 | import java.io.File;
21 | import java.nio.ByteBuffer;
22 | import java.util.ArrayList;
23 | import java.util.Arrays;
24 | import java.util.HashMap;
25 | import java.util.List;
26 | import java.util.Map;
27 | import org.antlr.runtime.ANTLRStringStream;
28 | import org.antlr.runtime.CharStream;
29 | import org.antlr.runtime.CommonTokenStream;
30 | import org.antlr.runtime.RecognitionException;
31 | import org.junit.Assert;
32 | import org.junit.Ignore;
33 | import org.junit.Test;
34 |
35 | /**
36 | *
37 | * @author darien.hager
38 | */
39 | public class ModelDataTest {
40 |
41 | static final String BUOY_MODEL = "buoy_ref.mdl";
42 | static final String PHY_MODEL = "buoy_ref.phy";
43 |
44 |
45 | protected static VdfRoot parseVdf(String data) throws RecognitionException {
46 | CharStream cs = new ANTLRStringStream(data);
47 | ValveTokenLexer lexer = new ValveTokenLexer(cs);
48 | SloppyParser parser = new SloppyParser(new CommonTokenStream(lexer));
49 | VdfRoot root = parser.main();
50 | return root;
51 | }
52 |
53 | @Test
54 | public void testBuoyModel() throws Exception {
55 |
56 | final int skinCount = 3;
57 |
58 | ByteBuffer bb = ParseUtil.mapFile(new File(this.getClass().getResource(BUOY_MODEL).toURI()));
59 | ModelData md = new ModelData(bb);
60 |
61 | Assert.assertEquals("props_swamp/buoy_ref.mdl", md.getModelName());
62 |
63 | Assert.assertEquals(skinCount, md.getSkinCount());
64 |
65 | List expectedPaths = new ArrayList();
66 | expectedPaths.add("materials/models/props_swamp/");
67 | Assert.assertEquals(expectedPaths, md.getTextureSearchPaths());
68 |
69 | /*
70 | * A quick explanation: MDLs store "skins" as a sort of replacement table.
71 | * Just because a texture appears in the list from getTexturesForSkin()
72 | * doesn't necessarily mean that it will be used, only that it would
73 | * replace whatever was in that same Nth position.
74 | */
75 | Map> expectedSkins = new HashMap>();
76 | expectedSkins.put(0, Arrays.asList(new String[]{"buoy_diffuse.vmt", "buoy_diffuse2.vmt","buoy_diffuse3.vmt"}));
77 | expectedSkins.put(1, Arrays.asList(new String[]{"buoy_diffuse2.vmt","buoy_diffuse2.vmt","buoy_diffuse3.vmt"}));
78 | expectedSkins.put(2, Arrays.asList(new String[]{"buoy_diffuse3.vmt","buoy_diffuse2.vmt","buoy_diffuse3.vmt"}));
79 |
80 | Map> actualSkins = new HashMap>();
81 | for(int i = 0; i < skinCount; i++){
82 | actualSkins.put(i, md.getTexturesForSkin(i));
83 | }
84 | Assert.assertEquals(expectedSkins, actualSkins);
85 |
86 |
87 | }
88 |
89 | @Test
90 | public void testBuoyPhy() throws Exception {
91 | ByteBuffer bb = ParseUtil.mapFile(new File(this.getClass().getResource(PHY_MODEL).toURI()));
92 |
93 | PhyData pd = new PhyData(bb);
94 |
95 | String rawPropData = pd.getPropData();
96 |
97 | VdfRoot root = parseVdf(rawPropData);
98 | PropDataReader pdr = new PropDataReader(root);
99 |
100 | //System.out.println(rawPropData);
101 |
102 | /*
103 | * TODO pick a different freely-distributable model with multiple gibs
104 | * Until then this isn't a very good test.
105 | */
106 | Assert.assertEquals(0, pdr.getAllGibs().size());
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/java/com/technofovea/hl2parse/registry/ClientRegistryTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.registry;
14 |
15 | import com.technofovea.hl2parse.ParseUtil;
16 | import com.technofovea.hl2parse.registry.CdrParser.AppDependency;
17 | import java.io.File;
18 | import java.io.IOException;
19 | import java.nio.ByteBuffer;
20 | import java.util.ArrayList;
21 | import java.util.Collections;
22 | import java.util.HashMap;
23 | import java.util.HashSet;
24 | import java.util.Iterator;
25 | import java.util.List;
26 | import java.util.Map;
27 | import java.util.Set;
28 | import org.apache.log4j.Level;
29 | import org.junit.Assert;
30 | import org.junit.Before;
31 | import org.junit.Ignore;
32 | import org.junit.Test;
33 |
34 | /**
35 | *
36 | * @author darien.hager
37 | */
38 | public class ClientRegistryTest {
39 |
40 | static final File BLOB_SOURCE = new File("c:\\Program Files\\Steam\\ClientRegistry.blob");
41 | static final int EXPECTED_VERSION = 1;
42 | static final int APPID_HALFLIFE = 70;
43 | static final int APPID_SOURCE_SDK = 211;
44 | private Map cachedAppNames = new HashMap();
45 |
46 | @Before
47 | public void setup() throws Exception {
48 | cachedAppNames.clear();
49 | }
50 |
51 | @Test
52 | public void parseClientRegistry() throws Exception {
53 |
54 | if(!BLOB_SOURCE.exists()){
55 | throw new IllegalStateException("Cannot test, Steam's clientregistry.blob does not exist on local machine. " +
56 | "Due to security concerns, it is not included with distributed code. " +
57 | "This test case looks for it in: "+BLOB_SOURCE.getAbsolutePath());
58 | }
59 | ByteBuffer buf = ParseUtil.mapFile(BLOB_SOURCE);
60 | BlobFolder root = RegParser.parseClientRegistry(buf);
61 | Assert.assertEquals("TopKey", root.getName());
62 | }
63 |
64 | @Test
65 | public void getContentDescriptionRecord() throws BlobParseFailure, IOException {
66 | ByteBuffer buf = ParseUtil.mapFile(BLOB_SOURCE);
67 | BlobFolder root = RegParser.parseClientRegistry(buf);
68 | ClientRegistry cr = new ClientRegistry(root);
69 | CdrParser cp = cr.getContentDescriptionRecord();
70 | String name = cp.getAppName(APPID_HALFLIFE);
71 | Assert.assertEquals("Half-Life", name);
72 |
73 | name = cp.getAppName(APPID_SOURCE_SDK);
74 | Assert.assertEquals("Source SDK", name);
75 |
76 |
77 | }
78 |
79 | @Test
80 | public void getAppDependencies() throws Exception {
81 |
82 | ByteBuffer buf = ParseUtil.mapFile(BLOB_SOURCE);
83 | BlobFolder root = RegParser.parseClientRegistry(buf);
84 | ClientRegistry cr = new ClientRegistry(root);
85 | CdrParser cp = cr.getContentDescriptionRecord();
86 |
87 | Set foundNames = new HashSet();
88 | List deps = cp.getAppDependencies(APPID_HALFLIFE);
89 | for (AppDependency i : deps) {
90 | foundNames.add(cp.getAppName(i.appid));
91 | }
92 |
93 | Set expectedNames = new HashSet();
94 | expectedNames.add("Half-Life Base Content");
95 | expectedNames.add("Base Goldsrc Shared Binaries");
96 | expectedNames.add("Base Goldsrc Shared Content");
97 | expectedNames.add("Base Goldsrc Shared Platform");
98 |
99 | Assert.assertEquals(expectedNames, foundNames);
100 |
101 | }
102 |
103 | private String getAppNameCached(CdrParser cp, int id) throws BlobParseFailure {
104 | if (cachedAppNames.containsKey(id)) {
105 | return cachedAppNames.get(id);
106 | }
107 | String s = cp.getAppName(id);
108 | cachedAppNames.put(id, s);
109 | return s;
110 | }
111 |
112 | @Ignore
113 | @Test
114 | public void printAppForWiki() throws Exception {
115 | Level origLogLevel = org.apache.log4j.Logger.getRootLogger().getLevel();
116 | org.apache.log4j.Logger.getRootLogger().setLevel(Level.OFF);
117 | ByteBuffer buf = ParseUtil.mapFile(BLOB_SOURCE);
118 | BlobFolder root = RegParser.parseClientRegistry(buf);
119 | ClientRegistry cr = new ClientRegistry(root);
120 | CdrParser cp = cr.getContentDescriptionRecord();
121 |
122 | Set appIdBag = new HashSet(cp.getAllAppIds());
123 | Set temp = new HashSet(appIdBag);
124 |
125 | Iterator iterScreen = temp.iterator();
126 | while(iterScreen.hasNext()){
127 | int id = iterScreen.next();
128 | List deps = cp.getAppDependencies(id);
129 | for (AppDependency dep : deps) {
130 | appIdBag.remove(dep.appid);
131 |
132 | }
133 | }
134 |
135 | List appIds = new ArrayList(appIdBag);
136 | Collections.sort(appIds);
137 | int limiter = 0;
138 | for (int id : appIds) {
139 | limiter++;
140 | String name = getAppNameCached(cp, id);
141 | if (name.startsWith("ValveTestApp")) {
142 | continue;
143 | }
144 | List deps = cp.getAppDependencies(id);
145 | Set tempset = new HashSet();
146 | String priString = "* '''" + id + " " + name + "''' ";
147 | String fname = cp.getAppFolderName(id);
148 | if(!name.equalsIgnoreCase(fname) && fname != null && (!"".equals(fname))){
149 | priString += "("+")";
150 | }
151 | System.out.println(priString);
152 | Iterator iter = deps.iterator();
153 | while (iter.hasNext()) {
154 | AppDependency dep = iter.next();
155 | if (tempset.contains(dep)) {
156 | iter.remove();
157 | } else {
158 | tempset.add(dep);
159 | }
160 | }
161 | Collections.sort(deps);
162 | for (AppDependency dep : deps) {
163 | if(dep.appid == id){
164 | continue;
165 | }
166 | String depString = "** " + dep.appid + " " + getAppNameCached(cp, dep.appid);
167 | if (dep.optional) {
168 | depString += " (optional)";
169 | }
170 | System.out.println(depString);
171 |
172 | }
173 |
174 |
175 |
176 | if (limiter > 500) {
177 | //break;
178 | }
179 | }
180 |
181 | org.apache.log4j.Logger.getRootLogger().setLevel(origLogLevel);
182 |
183 |
184 |
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/java/com/technofovea/hl2parse/xml/XmlTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2011 Darien Hager
3 | *
4 | * This code is part of the "HL2Parse" project, and is licensed under
5 | * a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
6 | * either a summary of conditions or the full legal text, please visit:
7 | *
8 | * http://creativecommons.org/licenses/by-sa/3.0/
9 | *
10 | * Permissions beyond the scope of this license may be available
11 | * at http://technofovea.com/ .
12 | */
13 | package com.technofovea.hl2parse.xml;
14 |
15 | import com.technofovea.hl2parse.vdf.ParseTest;
16 | import java.io.InputStream;
17 | import javax.xml.bind.JAXBContext;
18 | import javax.xml.bind.Marshaller;
19 | import javax.xml.bind.Unmarshaller;
20 | import org.junit.Assert;
21 | import org.junit.Test;
22 |
23 | /**
24 | *
25 | * @author Darien Hager
26 | */
27 | public class XmlTest {
28 |
29 | @Test
30 | public void go() throws Exception {
31 | InputStream is = ParseTest.class.getResourceAsStream("DefaultMaterials.xml");
32 | Assert.assertNotNull(is);
33 | JAXBContext jc = JAXBContext.newInstance(MaterialReference.class, MaterialRefList.class);
34 | Unmarshaller um = jc.createUnmarshaller();
35 | Marshaller m = jc.createMarshaller();
36 | m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
37 |
38 | Object o = um.unmarshal(is);
39 | System.out.println(o);
40 |
41 |
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/bsp/test_bsp_parse.bsp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DHager/hl2parse/4477e012e0b306c6758db4d6bad9065975f3ac78/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/bsp/test_bsp_parse.bsp
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/entdata/base.fgd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DHager/hl2parse/4477e012e0b306c6758db4d6bad9065975f3ac78/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/entdata/base.fgd
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/fgd/cyclic1.fgd:
--------------------------------------------------------------------------------
1 | @include "cyclic2.fgd"
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/fgd/cyclic2.fgd:
--------------------------------------------------------------------------------
1 | @include "cyclic1.fgd"
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/fgd/imported1.fgd:
--------------------------------------------------------------------------------
1 | @PointClass = Delta
2 | [
3 | erased(string) : "Wiped out by declaration in included file"
4 | ]
5 | @include "imported2.fgd"
6 |
7 | @PointClass = Beta
8 | [
9 | placeholder(string)
10 | ]
11 |
12 | @PointClass = Epsilon
13 | [
14 | eraser(string) : "Wipes out declaration in included file"
15 | ]
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/fgd/imported2.fgd:
--------------------------------------------------------------------------------
1 | @PointClass = Gamma
2 | [
3 | placeholder(string)
4 | ]
5 |
6 | @PointClass = Delta
7 | [
8 | eraser(string) : "Erases prior 'Delta' definition"
9 | ]
10 |
11 | @PointClass = Epsilon
12 | [
13 | erased(string) : "Wiped out declaration from the includer file"
14 | ]
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/fgd/importer.fgd:
--------------------------------------------------------------------------------
1 | @include "imported1.fgd"
2 |
3 | @PointClass = Alpha
4 | [
5 | placeholder(string)
6 | ]
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/fgd/inherit_test.fgd:
--------------------------------------------------------------------------------
1 | @BaseClass = Flying
2 | [
3 | maxheight(integer) : "Max flying height" : 0 : "The highest this thing can fly" +
4 | " before problems occur."
5 | ]
6 |
7 | @BaseClass = Machine
8 | [
9 | manufacturer(string) : "Manf. Name" : "" : "The name of the manufacturer"
10 | conflictingproperty(string): "TestingMachine" : "" : "A test property"
11 | ]
12 |
13 | @BaseClass = Animal
14 | [
15 | conflictingproperty(string): "TestingAnimal" : "" : "A test property"
16 | phylum(choices) : "Phylum" : 0 : "The animal phylum this entity belongs to" =
17 | [
18 | 0: "unspecified"
19 | 1: "porifera"
20 | 2: "cnidaria"
21 | 3: "ctenophora"
22 | 4: "platyhelminthes"
23 | 5: "nemertea"
24 | 6: "rotifera"
25 | 7: "gastrotricha"
26 | 8: "nematomorpha"
27 | 9: "nematoda"
28 | 10: "acanthocephala"
29 | 11: "bryozoa"
30 | 12: "tardigrada"
31 | 13: "brachiopoda"
32 | 14: "mollusca"
33 | 15: "annelida"
34 | 16: "sipunculoidea"
35 | 17: "arthropoda"
36 | 18: "chaetognatha"
37 | 19: "echinodermata"
38 | 20: "hemichordata"
39 | 21: "chordata"
40 | ]
41 | ]
42 |
43 | @PointClass base(Animal,Flying) = FlyingAnimal : "An animal which can fly"
44 | [
45 | wingcount(integer): "Wing count" : 2 : "Number of wings"
46 | ]
47 |
48 | @PointClass base(Machine,Flying) = FlyingMachine : "A machine which can fly"
49 | [
50 | engines(integer): "Engine count" : 2 : "Number of engines"
51 | ]
52 |
53 | @PointClass base(FlyingAnimal, FlyingMachine) = CyberBird : "A flying birdlike cyborg."
54 | [
55 | airating(integer): "AI rating" : 100 : "AI rating in adjusted IQ points"
56 | ]
57 |
58 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/fgd/overall.fgd:
--------------------------------------------------------------------------------
1 | @MaterialExclusion
2 | [
3 | // Names of the sub-directories we don't want to load materials from
4 | "alpha"
5 | "beta"
6 | "gamma/delta"
7 | ]
8 |
9 | @AutoVisGroup = "Tool Brushes"
10 | [
11 | "Vis Clusters"
12 | [
13 | "func_viscluster"
14 | ]
15 | ]
16 |
17 | @AutoVisGroup = "Custom"
18 | [
19 | "AI, Choreo"
20 | [
21 | "ai_speechfilter"
22 | "bot_controller"
23 | "bot_generator"
24 | "bot_hint_sentrygun"
25 | ]
26 |
27 | "Cameras"
28 | [
29 | "info_observer_point"
30 | "game_intro_viewpoint"
31 | "info_camera_link"
32 | ]
33 |
34 |
35 | "Sound"
36 | [
37 | "ambient_generic"
38 | "env_microphone"
39 | ]
40 | ]
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/mdl/buoy_ref.mdl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DHager/hl2parse/4477e012e0b306c6758db4d6bad9065975f3ac78/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/mdl/buoy_ref.mdl
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/mdl/buoy_ref.phy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DHager/hl2parse/4477e012e0b306c6758db4d6bad9065975f3ac78/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/mdl/buoy_ref.phy
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/utest.bsp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DHager/hl2parse/4477e012e0b306c6758db4d6bad9065975f3ac78/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/utest.bsp
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/Cloud001c.vmt:
--------------------------------------------------------------------------------
1 | "UnlitGeneric"
2 | {
3 | "$baseTexture" "skybox/Cloud001c"
4 | "$translucent" 1
5 | "$nofog" "1"
6 | "%keywords" "tf"
7 | }
8 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/GameConfig.txt:
--------------------------------------------------------------------------------
1 | "Configs"
2 | {
3 | "Games"
4 | {
5 | "Half-Life 2: Episode Two"
6 | {
7 | "GameDir" "c:\program files\steam\steamapps\STEAMLOGON\half-life 2 episode two\ep2"
8 | "hammer"
9 | {
10 | "GameData0" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\halflife2.fgd"
11 | "TextureFormat" "5"
12 | "MapFormat" "4"
13 | "DefaultTextureScale" "0.250000"
14 | "DefaultLightmapScale" "16"
15 | "GameExe" "c:\program files\steam\steamapps\STEAMLOGON\half-life 2 episode two\hl2.exe"
16 | "DefaultSolidEntity" "func_detail"
17 | "DefaultPointEntity" "info_player_start"
18 | "BSP" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vbsp.exe"
19 | "Vis" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vvis.exe"
20 | "Light" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vrad.exe"
21 | "GameExeDir" "c:\program files\steam\steamapps\STEAMLOGON\half-life 2 episode two"
22 | "MapDir" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk_content\ep2\mapsrc"
23 | "BSPDir" "c:\program files\steam\steamapps\STEAMLOGON\half-life 2 episode two\ep2\maps"
24 | "CordonTexture" "tools\toolsskybox"
25 | "MaterialExcludeCount" "0"
26 | }
27 | }
28 | "Team Fortress 2"
29 | {
30 | "GameDir" "c:\program files\steam\steamapps\STEAMLOGON\team fortress 2\tf"
31 | "hammer"
32 | {
33 | "GameData0" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\tf-abs.fgd"
34 | "TextureFormat" "5"
35 | "MapFormat" "4"
36 | "DefaultTextureScale" "0.250000"
37 | "DefaultLightmapScale" "16"
38 | "GameExe" "c:\program files\steam\steamapps\STEAMLOGON\team fortress 2\hl2.exe"
39 | "DefaultSolidEntity" "func_detail"
40 | "DefaultPointEntity" "prop_static"
41 | "BSP" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vbsp.exe"
42 | "Vis" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vvis.exe"
43 | "Light" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vrad.exe"
44 | "GameExeDir" "c:\program files\steam\steamapps\STEAMLOGON\team fortress 2"
45 | "MapDir" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk_content\tf\mapsrc"
46 | "BSPDir" "c:\program files\steam\steamapps\STEAMLOGON\team fortress 2\tf\maps"
47 | "CordonTexture" "tools\toolsskybox"
48 | "MaterialExcludeCount" "0"
49 | }
50 | }
51 | "Portal"
52 | {
53 | "GameDir" "c:\program files\steam\steamapps\STEAMLOGON\portal\portal"
54 | "hammer"
55 | {
56 | "GameData0" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\portal.fgd"
57 | "TextureFormat" "5"
58 | "MapFormat" "4"
59 | "DefaultTextureScale" "0.250000"
60 | "DefaultLightmapScale" "16"
61 | "GameExe" "c:\program files\steam\steamapps\STEAMLOGON\portal\hl2.exe"
62 | "DefaultSolidEntity" "func_detail"
63 | "DefaultPointEntity" "info_player_start"
64 | "BSP" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vbsp.exe"
65 | "Vis" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vvis.exe"
66 | "Light" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk\bin\orangebox\bin\vrad.exe"
67 | "GameExeDir" "c:\program files\steam\steamapps\STEAMLOGON\portal"
68 | "MapDir" "c:\program files\steam\steamapps\STEAMLOGON\sourcesdk_content\portal\mapsrc"
69 | "BSPDir" "c:\program files\steam\steamapps\STEAMLOGON\portal\portal\maps"
70 | "CordonTexture" "tools\toolsskybox"
71 | "MaterialExcludeCount" "0"
72 | }
73 | }
74 | }
75 | "SDKVersion" "3"
76 | }
77 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/SteamAppData.vdf:
--------------------------------------------------------------------------------
1 | "SteamAppData"
2 | {
3 | "RememberPassword" "0"
4 | "AutoLoginUser" "user@example.com"
5 | "terr_@hotmail.com"
6 | {
7 | "User" "user@example.com"
8 | "AccountCreated" "1"
9 | "ShowNotifyTrayHintDialog" "1"
10 | "hash" ""
11 | }
12 | }
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/ammo_red_bg.vmt:
--------------------------------------------------------------------------------
1 | "UnlitGeneric"
2 | {
3 | "LEVEL 3"
7 | }
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/glasswindow001a.vmt:
--------------------------------------------------------------------------------
1 | "LightmappedGeneric"
2 | {
3 | "$baseTexture" "glass/glasswindow001a"
4 | "$surfaceprop" "glass"
5 | "$translucent" 1
6 | "$envmap" "env_cubemap"
7 | "$envmapcontrast" ".5"
8 | // "$envmapsaturation" 1
9 | "$envmaptint" "[ .9 .9 .9]"
10 | "%keywords" "tf"
11 | "$basetexturetransform" "center .5 .5 scale 4 4 rotate 45 translate 0 0"
12 | }
13 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/particle_rockettrail1.vmt:
--------------------------------------------------------------------------------
1 | "UnlitGeneric"
2 | {
3 | // Original shader: BaseTimesVertexColorAlphaBlend
4 | "$basetexture" "particle/particle_rocketrail1"
5 | "$translucent" "1"
6 | // "$vertexcolor" "1"
7 | "$vertexalpha" "1"
8 | // "$additive" "1"
9 | }
10 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/particles_manifest.txt:
--------------------------------------------------------------------------------
1 | particles_manifest
2 | {
3 | "file" "!particles/error.pcf"
4 | "file" "!particles/rockettrail.pcf"
5 | "file" "particles/smoke_blackbillow.pcf"
6 | "file" "!particles/teleport_status.pcf"
7 | "file" "!particles/explosion.pcf"
8 | "file" "!particles/player_recent_teleport.pcf"
9 | "file" "!particles/rocketjumptrail.pcf"
10 | "file" "!particles/rocketbackblast.pcf"
11 | "file" "!particles/flamethrower.pcf"
12 | "file" "!particles/burningplayer.pcf"
13 | "file" "!particles/blood_impact.pcf"
14 | "file" "!particles/blood_trail.pcf"
15 | "file" "!particles/muzzle_flash.pcf"
16 | "file" "!particles/teleported_fx.pcf"
17 | "file" "!particles/cig_smoke.pcf"
18 | "file" "!particles/crit.pcf"
19 | "file" "!particles/medicgun_beam.pcf"
20 | "file" "!particles/water.pcf"
21 | "file" "!particles/stickybomb.pcf"
22 | "file" "!particles/buildingdamage.pcf"
23 | "file" "!particles/nailtrails.pcf"
24 | "file" "!particles/speechbubbles.pcf"
25 | "file" "!particles/bullet_tracers.pcf"
26 | "file" "!particles/nemesis.pcf"
27 | "file" "!particles/disguise.pcf"
28 | "file" "!particles/sparks.pcf"
29 | "file" "!particles/flag_particles.pcf"
30 | "file" "!particles/buildingdamage.pcf"
31 | "file" "!particles/shellejection.pcf"
32 | "file" "!particles/medicgun_attrib.pcf"
33 | "file" "!particles/item_fx.pcf"
34 | "file" "!particles/cinefx.pcf"
35 | "file" "!particles/impact_fx.pcf"
36 | "file" "!particles/conc_stars.pcf"
37 | "file" "!particles/class_fx.pcf"
38 | "file" "!particles/dirty_explode.pcf"
39 | "file" "!particles/smoke_blackbillow_hoodoo.pcf"
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/scorch1.vmt:
--------------------------------------------------------------------------------
1 | "DecalModulate"
2 | {
3 | "$translucent" 1
4 | "$basetexture" "Decals/scorch1"
5 | "$decal" 1
6 | "$decalscale" 0.25
7 | }
8 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/soundscapes_2fort.txt:
--------------------------------------------------------------------------------
1 | // DSP Effects
2 | // 0 : "Normal (off)"
3 | // 1 : "Generic"
4 | // 2 : "Metal Small"
5 | // 3 : "Metal Medium"
6 | // 4 : "Metal Large"
7 | // 5 : "Tunnel Small"
8 | // 6 : "Tunnel Medium"
9 | // 7 : "Tunnel Large"
10 | // 8 : "Chamber Small"
11 | // 9 : "Chamber Medium"
12 | // 10: "Chamber Large"
13 | // 11: "Bright Small"
14 | // 12: "Bright Medium"
15 | // 13: "Bright Large"
16 | // 14: "Water 1"
17 | // 15: "Water 2"
18 | // 16: "Water 3"
19 | // 17: "Concrete Small"
20 | // 18: "Concrete Medium"
21 | // 19: "Concrete Large"
22 | // 20: "Big 1"
23 | // 21: "Big 2"
24 | // 22: "Big 3"
25 | // 23: "Cavern Small"
26 | // 24: "Cavern Medium"
27 | // 25: "Cavern Large"
28 | // 26: "Weirdo 1"
29 | // 27: "Weirdo 2"
30 | // 28: "Weirdo 3"
31 |
32 | // ATTN_NONE 0.0f
33 | // ATTN_NORM 0.8f 75dB
34 | // ATTN_IDLE 2.0f 60dB
35 | // ATTN_STATIC 1.25f 66dB
36 | // ATTN_RICOCHET 1.5f 65dB
37 | // ATTN_GUNFIRE 0.27f 140dB
38 |
39 | // SNDLVL_50dB = 50, // 3.9
40 | // SNDLVL_55dB = 55, // 3.0
41 | // SNDLVL_IDLE = 60, // 2.0
42 | // SNDLVL_TALKING = 60, // 2.0
43 | // SNDLVL_60dB = 60, // 2.0
44 | // SNDLVL_65dB = 65, // 1.5
45 | // SNDLVL_STATIC = 66, // 1.25
46 | // SNDLVL_70dB = 70, // 1.0
47 | // SNDLVL_NORM = 75,
48 | // SNDLVL_75dB = 75, // 0.8
49 | // SNDLVL_80dB = 80, // 0.7
50 | // SNDLVL_85dB = 85, // 0.6
51 | // SNDLVL_90dB = 90, // 0.5
52 | // SNDLVL_95dB = 95,
53 | // SNDLVL_100dB = 100, // 0.4
54 | // SNDLVL_105dB = 105,
55 | // SNDLVL_120dB = 120,
56 | // SNDLVL_130dB = 130,
57 | // SNDLVL_GUNFIRE = 140, // 0.27
58 | // SNDLVL_140dB = 140, // 0.2
59 | // SNDLVL_150dB = 150, // 0.2
60 |
61 |
62 | "2fort.Underground"
63 | {
64 | "dsp" 1
65 |
66 |
67 | "playlooping"
68 | {
69 | volume ".6"
70 | "pitch" "100"
71 | "wave" ambient/underground.wav
72 | }
73 |
74 | "playlooping"
75 | {
76 | volume .30
77 | "pitch" "100"
78 | "wave" "ambient/machine_hum2.wav"
79 | }
80 |
81 | "playlooping"
82 | {
83 | "volume" ".75"
84 | "pitch" "100"
85 | "position" "0"
86 | "attenuation" "0.7"
87 | "wave" "ambient/machine_hum.wav"
88 | }
89 |
90 | "playlooping"
91 | {
92 | "volume" ".4"
93 | "pitch" "100"
94 | "position" "1"
95 | "attenuation" "0.7"
96 | "wave" "ambient/computer_tape.wav"
97 | }
98 |
99 | "playlooping"
100 | {
101 | "volume" ".75"
102 | "pitch" "100"
103 | "position" "2"
104 | "attenuation" "0.7"
105 | "wave" "ambient/computer_working.wav"
106 | }
107 |
108 | "playlooping"
109 | {
110 | "volume" ".4"
111 | "pitch" "100"
112 | "position" "3"
113 | "attenuation" "0.7"
114 | "wave" "ambient/computer_tape2.wav"
115 | }
116 |
117 | "playlooping"
118 | {
119 | "volume" ".75"
120 | "pitch" "100"
121 | "position" "4"
122 | "attenuation" "0.7"
123 | "wave" "ambient/command_center.wav"
124 | }
125 |
126 | "playlooping"
127 | {
128 | "volume" ".75"
129 | "pitch" "100"
130 | "position" "5"
131 | "attenuation" "0.7"
132 | "wave" "ambient/printer.wav"
133 | }
134 | }
135 |
136 | 2fort.Underground2
137 | {
138 | "dsp" "1"
139 |
140 |
141 | playlooping
142 | {
143 | "volume" ".6"
144 | "pitch" "100"
145 | "wave" "ambient/underground.wav"
146 | }
147 |
148 | "playlooping"
149 | {
150 | "volume" ".3"
151 | "pitch" "100"
152 | "wave" "ambient/machine_hum2.wav"
153 | }
154 |
155 | "playlooping"
156 | {
157 | "volume" ".75"
158 | "pitch" "100"
159 | "position" "0"
160 | "attenuation" "0.7"
161 | "wave" "ambient/machine_hum.wav"
162 | }
163 |
164 | "playlooping"
165 | {
166 | "volume" ".4"
167 | "pitch" "100"
168 | "position" "1"
169 | "attenuation" "0.7"
170 | "wave" "ambient/computer_tape.wav"
171 | }
172 |
173 | "playlooping"
174 | {
175 | "volume" ".75"
176 | "pitch" "100"
177 | "position" "2"
178 | "attenuation" "0.7"
179 | "wave" "ambient/computer_working.wav"
180 | }
181 |
182 | "playlooping"
183 | {
184 | "volume" ".4"
185 | "pitch" "100"
186 | "position" "3"
187 | "attenuation" "0.7"
188 | "wave" "ambient/computer_tape2.wav"
189 | }
190 |
191 | "playlooping"
192 | {
193 | "volume" ".85"
194 | "pitch" "100"
195 | "position" "4"
196 | "attenuation" "0.7"
197 | "wave" "ambient/command_center.wav"
198 | }
199 |
200 | "playlooping"
201 | {
202 | "volume" ".85"
203 | "pitch" "100"
204 | "position" "5"
205 | "attenuation" "0.7"
206 | "wave" "ambient/printer.wav"
207 | }
208 | }
209 |
210 | "2fort.OutdoorPond"
211 | {
212 | "dsp" "1"
213 |
214 | "playlooping"
215 | {
216 | "volume" ".35"
217 | "pitch" "100"
218 | "wave" "ambient/outdoors_quiet_birds.wav"
219 | }
220 |
221 | "playlooping"
222 | {
223 | "volume" ".35"
224 | "pitch" "100"
225 | "wave" "ambient/outdoors.wav"
226 | }
227 |
228 | "playlooping"
229 | {
230 | "volume" ".45"
231 | "pitch" "100"
232 | "wave" "ambient/pondlife.wav"
233 | }
234 |
235 | "playlooping"
236 | {
237 | "volume" ".15"
238 | "pitch" "100"
239 | "wave" "ambient/pondwater.wav"
240 | }
241 |
242 | "playrandom"
243 | {
244 | "time" "5,15"
245 | "volume" ".35"
246 | "pitch" "100"
247 | "position" "0"
248 | "attenuation" "0.25"
249 | "rndwave"
250 | {
251 | "wave" "ambient/cow1.wav"
252 | "wave" "ambient/cow2.wav"
253 | "wave" "ambient/cow3.wav"
254 | "wave" "ambient/bird1.wav"
255 | "wave" "ambient/bird2.wav"
256 | "wave" "ambient/bird3.wav"
257 | }
258 | }
259 |
260 | "playlooping"
261 | {
262 | "volume" ".35"
263 | "pitch" "100"
264 | "position" "1"
265 | "attenuation" "0.7"
266 | "wave" "ambient/train_engine_idle.wav"
267 | }
268 |
269 | "playlooping"
270 | {
271 | "volume" ".35"
272 | "pitch" "100"
273 | "position" "2"
274 | "attenuation" "0.7"
275 | "wave" "ambient/engine_idle.wav"
276 | }
277 |
278 | }
279 |
280 |
281 | "2fort.OutdoorFort"
282 | {
283 | "dsp" "1"
284 |
285 | "playlooping"
286 | {
287 | "volume" ".35"
288 | "pitch" "100"
289 | "wave" "ambient/outdoors_quiet_birds.wav"
290 | }
291 |
292 | "playlooping"
293 | {
294 | "volume" ".35"
295 | "pitch" "100"
296 | "wave" "ambient/outdoors.wav"
297 | }
298 |
299 |
300 | "playrandom"
301 | {
302 | "time" "5,15"
303 | "volume" ".35"
304 | "pitch" "100"
305 | "position" "0"
306 | "attenuation" "0.7"
307 | "rndwave"
308 | {
309 | "wave" "ambient/cow1.wav"
310 | "wave" "ambient/cow2.wav"
311 | "wave" "ambient/cow3.wav"
312 | "wave" "ambient/bird1.wav"
313 | "wave" "ambient/bird2.wav"
314 | "wave" "ambient/bird3.wav"
315 | }
316 | }
317 |
318 |
319 | "playlooping"
320 | {
321 | "volume" ".35"
322 | "pitch" "100"
323 | "position" "1"
324 | "attenuation" ".07"
325 | "wave" "ambient/factory_outdoor.wav"
326 | }
327 | }
328 |
329 | "2fort.Indoor"
330 | {
331 | "dsp" "1"
332 |
333 | "playlooping"
334 | {
335 | "volume" "1"
336 | "pitch" "100"
337 | "wave" "ambient/indoors.wav"
338 | }
339 | }
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/tf2_gameinfo.txt:
--------------------------------------------------------------------------------
1 | "GameInfo"
2 | {
3 | game "Team Fortress 2"
4 | gamelogo 1
5 | type multiplayer_only
6 | nomodels 1
7 | nohimodel 1
8 | nocrosshair 0
9 | hidden_maps
10 | {
11 | "test_speakers" 1
12 | "test_hardware" 1
13 | }
14 | nodegraph 0
15 | GameData "tf.fgd"
16 | InstancePath "maps/instances/"
17 | advcrosshair 1
18 |
19 |
20 | FileSystem
21 | {
22 | SteamAppId 440 // This will mount all the GCFs we need (240=CS:S, 220=HL2).
23 | ToolsAppId 211 // Tools will load this (ie: source SDK caches) to get things like materials\debug, materials\editor, etc.
24 |
25 | //
26 | // The code that loads this file automatically does a few things here:
27 | //
28 | // 1. For each "Game" search path, it adds a "GameBin" path, in \bin
29 | // 2. For each "Game" search path, it adds another "Game" path in front of it with _ at the end.
30 | // For example: c:\hl2\cstrike on a french machine would get a c:\hl2\cstrike_french path added to it.
31 | // 3. For the first "Game" search path, it adds a search path called "MOD".
32 | // 4. For the first "Game" search path, it adds a search path called "DEFAULT_WRITE_PATH".
33 | //
34 |
35 | //
36 | // Search paths are relative to the base directory, which is where hl2.exe is found.
37 | //
38 | // |gameinfo_path| points at the directory where gameinfo.txt is.
39 | // We always want to mount that directory relative to gameinfo.txt, so
40 | // people can mount stuff in c:\mymod, and the main game resources are in
41 | // someplace like c:\program files\valve\steam\steamapps\\half-life 2.
42 | //
43 | SearchPaths
44 | {
45 | Game |gameinfo_path|.
46 | Game tf
47 | Game |all_source_engine_paths|hl2
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/toolstrigger.vmt:
--------------------------------------------------------------------------------
1 | "LightmappedGeneric"
2 | {
3 | // Original shader: BaseTimesLightmapAlphaBlend
4 | "$translucent" 1
5 | "$basetexture" "Tools/toolstrigger"
6 | "%compiletrigger" 1
7 | "%keywords" "airexchange,borealis,c17downtown,c17industrial,c17sewers,c17skyscraper,c17trainstation,combine,kraken,wasteland"
8 | }
9 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/utest.ent:
--------------------------------------------------------------------------------
1 | {
2 | "world_maxs" "496 496 496"
3 | "world_mins" "-496 -496 16"
4 | "skyname" "some_sky_texture"
5 | "maxpropscreenwidth" "-1"
6 | "detailvbsp" "detail_custom.vbsp"
7 | "detailmaterial" "detail/detailsprites_custom"
8 | "classname" "worldspawn"
9 | "mapversion" "5"
10 | "hammerid" "1"
11 | }
12 | {
13 | "origin" "384 -384 128"
14 | "volstart" "0"
15 | "spinup" "0"
16 | "spindown" "0"
17 | "spawnflags" "48"
18 | "radius" "1250"
19 | "preset" "0"
20 | "pitchstart" "100"
21 | "pitch" "100"
22 | "message" "Ambient.Factory"
23 | "lfotype" "0"
24 | "lforate" "0"
25 | "lfomodvol" "0"
26 | "lfomodpitch" "0"
27 | "health" "10"
28 | "fadeoutsecs" "0"
29 | "fadeinsecs" "0"
30 | "cspinup" "0"
31 | "classname" "ambient_generic"
32 | "hammerid" "19"
33 | }
34 | {
35 | "origin" "320 -384 128"
36 | "volstart" "0"
37 | "spinup" "0"
38 | "spindown" "0"
39 | "spawnflags" "48"
40 | "radius" "1250"
41 | "preset" "0"
42 | "pitchstart" "100"
43 | "pitch" "100"
44 | "message" "ambient/alarms/warningbell1.wav"
45 | "lfotype" "0"
46 | "lforate" "0"
47 | "lfomodvol" "0"
48 | "lfomodpitch" "0"
49 | "health" "10"
50 | "fadeoutsecs" "0"
51 | "fadeinsecs" "0"
52 | "cspinup" "0"
53 | "classname" "ambient_generic"
54 | "hammerid" "34"
55 | }
56 | {
57 | "origin" "256 -384 128"
58 | "SunSpreadAngle" "0"
59 | "pitch" "0"
60 | "angles" "0 0 0"
61 | "_lightscaleHDR" "1"
62 | "_lightHDR" "-1 -1 -1 1"
63 | "_light" "255 255 255 200"
64 | "_AmbientScaleHDR" "1"
65 | "_ambientHDR" "-1 -1 -1 1"
66 | "_ambient" "255 255 255 20"
67 | "classname" "light_environment"
68 | "hammerid" "68"
69 | }
70 | {
71 | "origin" "192 -384 128"
72 | "start_active" "0"
73 | "effect_name" "some_particle_system"
74 | "cpoint7_parent" "0"
75 | "cpoint6_parent" "0"
76 | "cpoint5_parent" "0"
77 | "cpoint4_parent" "0"
78 | "cpoint3_parent" "0"
79 | "cpoint2_parent" "0"
80 | "cpoint1_parent" "0"
81 | "angles" "0 0 0"
82 | "classname" "info_particle_system"
83 | "hammerid" "75"
84 | }
85 | {
86 | "origin" "384 -320 128"
87 | "soundscape" "custom.soundscape"
88 | "radius" "128"
89 | "classname" "env_soundscape"
90 | "hammerid" "341"
91 | }
92 |
93 |
94 |
--------------------------------------------------------------------------------
/hl2parse-tests/src/test/resources/com/technofovea/hl2parse/vdf/water_2fort.vmt:
--------------------------------------------------------------------------------
1 | "Water"
2 | {
3 |
4 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/license_header.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 2011 Darien Hager
2 |
3 | This code is part of the "HL2Parse" project, and is licensed under
4 | a Creative Commons Attribution-ShareAlike 3.0 Unported License. For
5 | either a summary of conditions or the full legal text, please visit:
6 |
7 | http://creativecommons.org/licenses/by-sa/3.0/
8 |
9 | Permissions beyond the scope of this license may be available
10 | at http://technofovea.com/ .
11 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | HL2Parse is a library for interpreting certain files from Valve Software and the "Source" game engine.
2 |
3 | You may use it through the Maven repository by adding the following to your POM:
4 |
5 |
6 |
7 | dhager-github
8 | DHager's Github Maven Repository
9 | http://dhager.github.com/mvn-repo/releases
10 |
11 |
--------------------------------------------------------------------------------