/* * Copyright (C) 2015 iZc * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package de.nplusc.izc.logblockheatmapper; import ar.com.hjg.pngj.ImageInfo; import ar.com.hjg.pngj.ImageLineHelper; import ar.com.hjg.pngj.ImageLineInt; import ar.com.hjg.pngj.PngWriter; import ar.com.hjg.pngj.chunks.PngChunkTextVar; import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.*; import java.util.*; import javax.imageio.ImageIO; /** * * @author iZc */ enum BlockState { NONE, BUFFER, ACTIVITY, BUFFER_PURGED, ACTIVITY_PURGED, WORKBENCH_FORCED, WORKBENCH_FORCED_BUFFER, } enum RegionState { REMOVE, CORE, KEEP, WATERIZE, DROPPED } class CoordHolder { public final int x; public final int y; public final int z; public final String blocktype; CoordHolder(int x, int y, int z, String blocktype) { this.x = x; this.y = y; this.z = z; this.blocktype = blocktype; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CoordHolder that = (CoordHolder) o; return x == that.x && y == that.y && z == that.z && Objects.equals(blocktype, that.blocktype); } @Override public int hashCode() { return Objects.hash(x, y, z, blocktype); } } public class LogBlockHeatmapperRegionTrimmer { static final int treshold = 100; static final int buffer = 30; static final int workbenchbuffer = 50; static final List blocktypes = Arrays.asList( "minecraft:crafting_table", "minecraft:furnace", "minecraft:barrel", "minecraft:ender_chest", "minecraft:shulker_box", "minecraft:black_shulker_box", "minecraft:gray_shulker_box", "minecraft:white_shulker_box", "minecraft:light_gray_shulker_box", "minecraft:red_shulker_box", "minecraft:pink_shulker_box", "minecraft:purple_shulker_box", "minecraft:magenta_shulker_box", "minecraft:orange_shulker_box", "minecraft:brown_shulker_box", "minecraft:cyan_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:green_shulker_box", "minecraft:blue_shulker_box", "minecraft:hopper", "minecraft:chest" ); //x y static final Color removeA = new Color(255, 127, 39); static final Color removeB = new Color(251, 100, 0); static final Color removeA_Dropped = new Color(255, 13, 90); static final Color removeB_Dropped = new Color(255, 13, 120); static final Color keepA = new Color(128, 255, 0); static final Color keepB = new Color(0, 255, 64); static final Color waterA = new Color(0, 128, 192); static final Color waterB = new Color(0, 128, 255); static final Color keepCoreA = new Color(0, 64, 0); static final Color keepCoreB = new Color(0, 106, 0); static final Color activity = new Color(87, 87, 87); static final Color activityBuffer = new Color(157, 157, 157); static final Color activityPurged = new Color(230, 230, 230); static final Color activityBufferPurged = new Color(255, 255, 255); static final Color workbench_keep = new Color(255, 255, 0); static final Color workbench_keep_buffer = new Color(128, 128, 0); static final Color coreEdge = new Color(255, 0, 0); static int[ ][ ] dataField ; static Map keepRegionsIn = new TreeMap<>(); static Map keepRegions = new TreeMap<>(); static Map workbenchCalculations = new HashMap<>(); static int radius=0; static int coreRadius=0; static int regionRedius = 0; static int fuckyou = 0; private static void setRegion(int x,int y, int s) { int rx = (int)Math.floor((x)/512.0f); int ry = (int)Math.floor((y)/512.0f); keepRegionsIn.putIfAbsent(("r."+rx+"."+ry+".mca"),0); keepRegionsIn.put(("r."+rx+"."+ry+".mca"),keepRegionsIn.get(("r."+rx+"."+ry+".mca"))+s); } private static void setRegionFinal(int x,int y, RegionState s) { int rx = (int)Math.floor((x)/512.0f); int ry = (int)Math.floor((y)/512.0f); keepRegions.put(("r."+rx+"."+ry+".mca"),s); } /** * @param args the command line arguments * @throws java.lang.Exception */ public static void main(String[] args)throws Exception { if(args.length<3) { throw new UnsupportedOperationException("not enough parameters"); } /* if(args.length>2) { targetBlockID = Integer.valueOf(args[2]); if(args.length>3) { removalsOnly = Boolean.valueOf(args[3]); } }*/ radius = Integer.valueOf(args[1]); dataField = new int[radius*2][radius*2]; int regionBase = radius/512; int regionRemainder = radius%512; if(regionRemainder>0) { regionBase++; } coreRadius = Integer.valueOf(args[2]); int coreBase = coreRadius/512; int coreRemainder = coreRadius%512; if(coreRemainder>0) { coreBase++; } regionRedius = regionBase; for(int i=0;i { //4 als 5 und nen bisschen arithmetik gibt seitwärts-schnittansicht //id_0 oldblox_1 newblox_2 newdv_3 X_4 height_5 y_6 //10 5 0 0 -1373 27 4008 xx = xx.replace("\"", ""); xx = xx.replace(",", "\t"); String[] xes = xx.split("\\t"); int l = Integer.parseInt(xes[0]); boolean register=false; String to = xes[2].intern(); String from = xes[3].intern(); //richtigrum, verfickt und zugenäht int x= Integer.parseInt(xes[4])+radius,y= Integer.parseInt(xes[6])+radius; int z = Integer.parseInt(xes[5]); if(blocktypes.contains(from)||blocktypes.contains(to)) { if(from!=to) // yes, this works since i interned the strings beforehand :P { fuckyou++; lmaa.println(xx); if(blocktypes.contains(from)) { CoordHolder location = new CoordHolder(x,y,z,from); if(!workbenchCalculations.containsKey(location)) { workbenchCalculations.put(location,-1); } else { workbenchCalculations.put(location,workbenchCalculations.get(location)-1); } } if(blocktypes.contains(to)) { CoordHolder location = new CoordHolder(x,y,z,to); if(!workbenchCalculations.containsKey(location)) { workbenchCalculations.put(location,1); } else { workbenchCalculations.put(location,workbenchCalculations.get(location)+1); } } } else { //System.out.print("Skipped Transaction due to from and to being equal"); } } else { //-y=up if(x=0&&y=0) { for(int i=-buffer;i0) { for(int j=-buffer;j<+1;j++) { if((y+j)<(radius*2)&&(y+j)>0) { //only switching NONE to BUFFER if(dataField[y+j][x+i]==BlockState.NONE.ordinal()) { dataField[y+j][x+i]=BlockState.BUFFER_PURGED.ordinal(); // setRegion(x+i-radius, y+i-radius, 1); // propagating buffer markers in second pass... buffer rendering handled in same pass } } } } } dataField[y][x]=BlockState.ACTIVITY.ordinal(); setRegion(x-radius, y-radius, 1); } } if(l%10000==0) { System.out.print(l+"changes so far\r"); } }); System.out.println("\n"); System.out.println(fuckyou); System.out.println("\nDatabase crunched to 100%\n"); System.out.print("\nCalculating Workbenches("+workbenchCalculations.size()+") \n"); lmaa.close(); workbenchCalculations.forEach((c,i) -> { if(i>0) { System.out.println("workbench at"+c.x+"|"+c.y); if(c.x<0||c.y<0||c.x>=dataField.length||c.y>=dataField.length) { return; } System.out.println("workbench kept at"+c.x+"|"+c.y+"| cnt = "+i); setRegion(c.x-radius,c.y-radius,3*treshold); // force keep dataField[c.y][c.x]=BlockState.WORKBENCH_FORCED.ordinal(); } if(i<-1) { System.out.println("DAFUQ at"+c.x+"|"+c.y+"| as "+i); } }); System.out.println("\nWorkbenches calculated\n"); for(int i=-regionBase;i<=regionBase;i++) { for(int j=-regionBase;j<=regionBase;j++) { int current=keepRegionsIn.getOrDefault(("r."+(i)+"."+(j)+".mca"),-1); System.out.println("Processing r."+(i)+"."+(j)+".mca; ("+i+"/"+regionBase+"|"+j+"/"+regionBase); if(current0) // no activity inside so no need to search for activity spots { //highlighgt actively dropped ones differently... if(((old)!=RegionState.CORE)&&(old!=RegionState.KEEP)) { System.out.println("Dropping r."+(i)+"."+(j)+".mca; Is: "+old); keepRegions.put(("r."+(i)+"."+(j)+".mca"),RegionState.DROPPED); } for(int pi = 0;pi<512;pi++) { for(int pj = 0;pj<512;pj++) { int kx = i*512+pi+radius+1; int ky = j*512+pj+radius+1; if(kx<0||ky<0||kx>=dataField.length||ky>=dataField.length) { continue; // coordinate not valid. can't crunch } BlockState k = BlockState.values()[dataField[ky][kx]]; if(k==BlockState.ACTIVITY) { dataField[ky][kx]=BlockState.ACTIVITY_PURGED.ordinal(); } } } } } else { keepRegions.put(("r."+(i)+"."+(j)+".mca"),RegionState.KEEP); for(int pi = 0;pi<512;pi++) { for(int pj = 0;pj<512;pj++) { int kx = i*512+pi+radius; int ky = j*512+pj+radius; if(kx<0||ky<0||kx>=dataField.length||ky>=dataField.length) { continue; // coordinate not valid. can't crunch } BlockState k = BlockState.values()[dataField[ky][kx]]; if(k==BlockState.ACTIVITY) { if(pimax&&pj>max) { keepRegions.put(("r."+(i+1)+"."+(j+1)+".mca"),RegionState.KEEP); } if(pi>max) { keepRegions.put(("r."+(i+1)+"."+(j)+".mca"),RegionState.KEEP); } if (pj>max) { keepRegions.put(("r."+(i)+"."+(j+1)+".mca"),RegionState.KEEP); } //propagating buffers int kxmin = Math.max(0,kx-(buffer+1)); int kymin = Math.max(0,ky-(buffer+1)); int kxmax = Math.min(dataField.length,kx+buffer+1); int kymax = Math.min(dataField.length,ky+buffer+1); for(int ki = kxmin;kimax&&pj>max) { keepRegions.put(("r."+(i+1)+"."+(j+1)+".mca"),RegionState.KEEP); } if(pi>max) { keepRegions.put(("r."+(i+1)+"."+(j)+".mca"),RegionState.KEEP); } if (pj>max) { keepRegions.put(("r."+(i)+"."+(j+1)+".mca"),RegionState.KEEP); } //propagating buffers int kxmin = Math.max(0,kx-(workbenchbuffer+1)); int kymin = Math.max(0,ky-(workbenchbuffer+1)); int kxmax = Math.min(dataField.length,kx+(workbenchbuffer+1)); int kymax = Math.min(dataField.length,ky+(workbenchbuffer+1)); for(int ki = kxmin;ki { switch(v) { case REMOVE: case DROPPED: fileActions.println("mv "+k+" oldChunks/"); System.out.println("mv "+k+" oldChunks/"); break; case CORE: fileActions.println("echo "+k+" is keepCore"); System.out.println("echo "+k+" is keepCore"); break; case KEEP: fileActions.println("echo "+k+" is keep"); System.out.println("echo "+k+" is keep"); break; case WATERIZE: fileActions.println("mv "+k+" oldChunksWaterize/"); System.out.println("mv "+k+" oldChunksWaterize/"); fileActions.println("mv waterize/"+k+" ./"); System.out.println("mv waterize/"+k+" ./"); break; } }); fileActions.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } } } //use mcserver; //mysql> SELECT id,replaced,type,data,x,y,z from `lb-surv` into outfile D:\\emc2\\arca_slash\\heatmap.tsv FIELDS TERMINATED BY `\t` LINES TERMINATED BY `\n` /* SELECT blocks.id, blocks.id, blocks.type, blocks.replaced, blocks.x,blocks.y, blocks.z FROM `lb-players` as player, `lb-surv-blocks` as blocks where player.playerid = blocks.playerid AND player.UUID NOT LIKE 'l%' INTO OUTFILE 'C:/lmaa/crunchme/survival2-oct-novirt.csv' ; */ /* SELECT blocks.id, blocks.id, materials.name, materials2.name, blocks.x,blocks.y, blocks.z FROM `lb-players` as player, `lb-surv-blocks` as blocks, `lb-materials` as materials, `lb-materials` as materials2 where player.playerid = blocks.playerid AND player.UUID NOT LIKE 'l%' and blocks.type = materials.id and blocks.replaced = materials2.id INTO OUTFILE '/tmp/crunchy.csv'; * */