📄 waddata.java
字号:
* Loads the ap cache into a special place set accessable under * the place set name APs. This is used so we can display the * aps on maps like we do with places. * @param useIcon you must provide an ImageData to use as an * icon for the place, because every place must have an icon, and * I surely don't have one laying around. * @return the place set for the aps */ public Hashtable loadAPCacheAsPlaces(ImageData useIcon) throws IOException, WadDataFormatException { if(!containsAPCache()) { throw new WadDataFormatException(myApCacheKey, WadDataFormatException.MISSING_RESOURCE_ERROR, "cannot load the ap cache if it doesn't exist."); } Hashtable apSet = new Hashtable(); BufferedReader br = new BufferedReader(new InputStreamReader( wad.getInputStream(wad.getEntry(myApCacheKey)))); String line; while((line = br.readLine()) != null) { String tokens[] = StringUtil.split(line); if(tokens.length != 4) { // its too draconian to ask that the ap caches // have every line be perfect, because they just don't // in practice. No, I have no idea why. continue; } double apLat; double apLon; try { apLat = Double.parseDouble(tokens[0]); apLon = Double.parseDouble(tokens[1]); } catch(NumberFormatException nfe) { continue; } String name = tokens[2]; // mac address isn't really interesting for a place // but I use it as the key in the hashtable, since that // way it doesn't get the same ap twice String mac = StringUtil.canonicalizeBSSID(tokens[3]); PlaceBacking apPlace = new PlaceBacking("AP", name, "", "wireless access point: " + name, apLat, apLon, "ap icon", useIcon); apSet.put(mac, apPlace); } places.put("APs", apSet); return apSet; } /* methods for accessing/mutating the WadData */ public MapBacking getMap(String mapName) { return (MapBacking)maps.get(mapName); } public Hashtable getMaps() { return maps; } public void putMap(BitmapMapBacking map) { maps.put(map.getName(), map); } public Enumeration getPlaceSetNames() { return places.keys(); } public RegionBacking getRegion(String regionName) { return (RegionBacking)regions.get(regionName); } public Hashtable getRegions() { return regions; } public void putRegion(RegionBacking region) { regions.put(region.getName(), region); } /** * Writes out the current state of the waddata as a zip file to the supplied OutputStream * Note that since images from waddata are lazily loaded you should <b>not</b> do this: * <code> * WadData wad = new WadData(somePath); * wad.putRegion(someRegionYouWantToAdd); * wad.saveWad(new FileOutputStream(somePath))); * </code> * If you do the above, it will break because the wad may need to load the image data * from disk as it is copying them, but those images are now gone. If you want to do this * use the {@link #saveWad()} method instead, which will manage setting up a temporary file * for you to get around this problem. * @throws IOException */ public void saveWad(OutputStream out) throws IOException { ZipOutputStream zip = new ZipOutputStream(out); // start by writing out the defaults.txt if there are defaults if(this.getDefaultMap() != null) { Hashtable defaultsTXT = new Hashtable(); Hashtable defaultMapFields = new Hashtable(); defaultMapFields.put(this.getDefaultMap().getName(), "1"); defaultsTXT.put("Map", defaultMapFields); if(this.getDefaultPlaceSets() != null) { Hashtable defaultPlaceFields = new Hashtable(); Enumeration e = this.getDefaultPlaceSets().keys(); while(e.hasMoreElements()) { defaultPlaceFields.put((String)e.nextElement(), "1"); } defaultsTXT.put("Places", defaultPlaceFields); } zip.putNextEntry(new ZipEntry("defaults.txt")); SectionedFileParser.write(defaultsTXT, zip); } // now write out the map index and then all of the maps // put a directory entry for the map zip.putNextEntry(new ZipEntry(WadData.mapsDirKey)); zip.closeEntry(); // also put an images directory zip.putNextEntry(new ZipEntry("images/")); zip.closeEntry(); Hashtable mapsIndexTXT = new Hashtable(); Hashtable mapsIndexMapEntry = new Hashtable(); Enumeration e = this.getMaps().keys(); while(e.hasMoreElements()) { String mapname = (String)e.nextElement(); mapsIndexMapEntry.put(mapname, mapname + ".meta"); } mapsIndexTXT.put("Maps", mapsIndexMapEntry); zip.putNextEntry(new ZipEntry(WadData.mapsIndexKey)); SectionedFileParser.write(mapsIndexTXT, zip); zip.closeEntry(); // now write out the images and map.txt files for all the maps e = this.getMaps().elements(); while(e.hasMoreElements()) { MapBacking mapBacking = (MapBacking)e.nextElement(); if(mapBacking instanceof BitmapMapBacking) { BitmapMapBacking map = (BitmapMapBacking)mapBacking; ImageData image = map.getImageResource(); String imageName = "images/" + map.getName() + ".jpg"; this.saveImage(zip, new ZipEntry(imageName), image); // now write out the meta file zip.putNextEntry(new ZipEntry(WadData.mapsDirKey + map.getName() + ".meta")); Hashtable mapMetaTXT = new Hashtable(); Hashtable mapMetaEntry = new Hashtable(); mapMetaEntry.put("origin_lat", Double.toString(map.getOriginLat())); mapMetaEntry.put("origin_lon", Double.toString(map.getOriginLon())); mapMetaEntry.put("upper_right_lat", Double.toString(map.getMaxLat())); mapMetaEntry.put("upper_right_lon", Double.toString(map.getMaxLon())); mapMetaEntry.put("image", imageName); mapMetaTXT.put("Map", mapMetaEntry); SectionedFileParser.write(mapMetaTXT, zip); } else { // TODO: tiger support } } // now do places.index // put a directory for places zip.putNextEntry(new ZipEntry(WadData.placesDirKey)); zip.closeEntry(); Hashtable placesIndexTXT = new Hashtable(); Hashtable placesIndexEntry = new Hashtable(); e = this.allPlaceSets().keys(); while(e.hasMoreElements()) { String placename = (String)e.nextElement(); placesIndexEntry.put(placename, placename + ".meta"); } placesIndexTXT.put("Places", placesIndexEntry); zip.putNextEntry(new ZipEntry(WadData.placesIndexKey)); SectionedFileParser.write(placesIndexTXT, zip); // now do each place.meta e = this.allPlaceSets().keys(); while(e.hasMoreElements()) { Hashtable placeSetMetaTXT = new Hashtable(); String placeSetName = (String)e.nextElement(); Hashtable placeSet = this.getPlaceSet(placeSetName); Enumeration e2 = placeSet.keys(); while(e2.hasMoreElements()) { String placeName = (String)e2.nextElement(); PlaceBacking place = (PlaceBacking)placeSet.get(placeName); String iconName = "images/" + placeName + ".jpg"; this.saveImage(zip, new ZipEntry(iconName), place.getImageResource()); Hashtable placeEntry = new Hashtable(); placeEntry.put("icon_file", iconName); placeEntry.put("lat", Double.toString(place.lat)); placeEntry.put("lon", Double.toString(place.lon)); placeEntry.put("text", place.text); placeEntry.put("type", place.type); placeEntry.put("url", place.url); placeSetMetaTXT.put(placeName, placeEntry); } zip.putNextEntry(new ZipEntry(WadData.placesDirKey + placeSetName + ".meta")); SectionedFileParser.write(placeSetMetaTXT, zip); } // now do the regions zip.putNextEntry(new ZipEntry(WadData.regionsDirKey)); zip.closeEntry(); Hashtable regionsIndexTXT = new Hashtable(); Hashtable regionsIndexEntry = new Hashtable(); e = this.regions.keys(); while(e.hasMoreElements()) { String regionName = (String)e.nextElement(); regionsIndexEntry.put(regionName, regionName + ".meta"); } regionsIndexTXT.put("Regions", regionsIndexEntry); zip.putNextEntry(new ZipEntry(WadData.regionsIndexKey)); SectionedFileParser.write(regionsIndexTXT, zip); e = this.regions.elements(); while(e.hasMoreElements()) { RegionBacking region = (RegionBacking)e.nextElement(); Hashtable regionMetaTXT = new Hashtable(); Hashtable regionMetaEntry = new Hashtable(); regionMetaEntry.put("origin_lat", Double.toString(region.originLat)); regionMetaEntry.put("origin_lon", Double.toString(region.originLon)); regionMetaEntry.put("upper_right_lat", Double.toString(region.upperRightLat)); regionMetaEntry.put("upper_right_lon", Double.toString(region.upperRightLon)); regionMetaEntry.put("text", region.text); regionMetaTXT.put("Region", regionMetaEntry); zip.putNextEntry(new ZipEntry(WadData.regionsDirKey + region.name + ".meta")); SectionedFileParser.write(regionMetaTXT, zip); } // TODO: write apcache.txt zip.close(); } public void saveWad() throws IOException { if(this.wadPath == null) { throw new IllegalStateException("You cannot save a wad that you haven't opened"); } File temp = File.createTempFile("save", "mapwad"); this.saveWad(new FileOutputStream(temp)); File original = new File(this.wadPath); this.wad.close(); if(!original.delete()) { throw new IOException("couldn't delete old file"); } temp.renameTo(original); wad = new ZipFile(wadPath); } /** * @return a Hashtable where place set names => * Hashtables where place names => PlaceBackings */ public Hashtable allPlaceSets() { return this.places; } public Hashtable getPlaceSet(String setName) { return (Hashtable)places.get(setName); } public PlaceBacking getPlace(String setName, String placeName) { Hashtable set = getPlaceSet(setName); if(set != null) { return (PlaceBacking)set.get(placeName); } else { return null; } } public void putPlaceSet(String setName, Hashtable set) { places.put(setName, set); } public void addPlace(String setName, PlaceBacking place) { Hashtable set = getPlaceSet(setName); if(set != null) { set.put(place.name, place); } } /** * Returns the MapBacking specified as the default for the wad * or null if no MapBacking is specified */ public MapBacking getDefaultMap() { if(defaultMap == null) return null; else return getMap(defaultMap); } /** * Returns a Hashtable containing the default place sets * (Hashtables of PlaceBackings) for the * wad or null if no default place sets are specified. */ public Hashtable getDefaultPlaceSets() { return defaultPlaces; } /* little helpers */ private void saveImage(ZipOutputStream out, ZipEntry at, ImageData image) throws IOException { ImageLoader imageWriter = new ImageLoader(); imageWriter.data = new ImageData[1]; imageWriter.data[0] = image; out.putNextEntry(at); try { // image writer's save method will close the underlying output stream // bad image writer, bad! so i fake it out ByteArrayOutputStream baos = new ByteArrayOutputStream(); //imageWriter.save(out, image.type); imageWriter.save(baos, SWT.IMAGE_JPEG); out.write(baos.toByteArray()); } catch(SWTException swte) { throw new IOException("couldn't write image " + at.getName() + "with error: " + swte.toString()); } out.closeEntry(); } private String basename(String path) { return path.substring(path.lastIndexOf('/') + 1, path.length() - 1); } private boolean containsResource(String path) { ZipEntry entry = wad.getEntry(path); return !(entry == null || entry.isDirectory()); } public InputStream getArbitraryResource(String path) throws IOException { if(!containsResource(path)) return null; return wad.getInputStream(wad.getEntry(path)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -