· 4 years ago · Feb 02, 2021, 09:12 AM
1package zmaster587.advancedRocketry.threads;
2
3import java.sql.*;
4import java.util.ArrayList;
5//import java.util.HashMap;
6//import java.util.LinkedList;
7import java.util.HashMap;
8import java.util.Random;
9import java.util.List;
10
11import zmaster587.advancedRocketry.api.ARConfiguration;
12import zmaster587.advancedRocketry.util.AsteroidSmall;
13
14public class AsteroidsThread extends Thread{
15 private Connection c = null;
16 private Statement stmt = null;
17 private Random generator = new Random();
18 private HashMap<String, Float> guaranteed_random = new HashMap<String, Float>();
19 private float MAX_PROPABILITY = 0.0F;
20 //HashMap<String, AsteroidSmall> asteroidTypes = new HashMap<String, AsteroidSmall>();
21 private ARConfiguration cfg = null;
22 private final static int MAX_DB_ASTEROIDS = 500;
23 private final int sleepDelayMs = 100;
24 private final int dbCheckDelayMs = 10000/sleepDelayMs;
25 private final int ASTEROID_ALIVE_TIME_SEC = 10;//will multiply to mass
26 private final int DB_SQLITE_SEQ_OFV = 2147483647 - MAX_DB_ASTEROIDS;
27 //private final int DB_SQLITE_SEQ_OFV = 250;
28 private final RANDOM_STRATEGY selectedRandomStrategy = RANDOM_STRATEGY.RANDOM_STRATEGY_RANDOM;
29 private List<AsteroidSmall> asteroidTemplate = new ArrayList<AsteroidSmall>();
30 //private HashMap<String, AsteroidSmall> asteroidTypes = new HashMap<String, AsteroidSmall>();
31
32 private enum RANDOM_STRATEGY
33 {
34 RANDOM_STRATEGY_RANDOM,
35 RANDOM_STRATEGY_GUARANTEED
36 }
37
38 public void setConfig (ARConfiguration config)
39 {
40 this.cfg = config;
41 }
42 public AsteroidSmall getAsteroidTemplate(String str)
43 {
44 return ARConfiguration.getCurrentConfig().asteroidTypes.get(str);
45 }
46
47 private void init()
48 {
49 //this.asteroidTemplate = ARConfiguration.getCurrentConfig().asteroidTypes;
50 for(String str : ARConfiguration.getCurrentConfig().asteroidTypes.keySet()) {
51 System.out.println("init() str:"+str);
52 AsteroidSmall asteroid = ARConfiguration.getCurrentConfig().asteroidTypes.get(str);
53 this.asteroidTemplate.add(asteroid);
54 }
55 }
56 List<AsteroidSmall> generateAsteroidsGuaranteed()
57 {
58 List<AsteroidSmall> to_generate = new ArrayList<AsteroidSmall>();
59 if (this.guaranteed_random.size() == 0)
60 {
61 for (AsteroidSmall asteroid : this.asteroidTemplate)
62 {
63 this.guaranteed_random.put(asteroid.getName(), 0.0F);
64 this.MAX_PROPABILITY = Math.max(asteroid.probability, this.MAX_PROPABILITY);
65 }
66 }
67 for (AsteroidSmall asteroid : this.asteroidTemplate)
68 {
69 float probability = this.guaranteed_random.get(asteroid.getName()) + asteroid.probability;
70 if (probability >= MAX_PROPABILITY)
71 {
72 to_generate.add(asteroid);
73 probability -= MAX_PROPABILITY;
74 if (probability > MAX_PROPABILITY)//mean chance is too high. prevent overflow
75 {
76 probability = 0;
77 }
78 }
79 this.guaranteed_random.put(asteroid.getName(), probability);
80 }
81 return to_generate;
82 }
83 List<AsteroidSmall> generateAsteroidsRandom()
84 {
85 float chance = this.generator.nextFloat();
86 List<AsteroidSmall> to_generate = new ArrayList<AsteroidSmall>();
87 for (AsteroidSmall asteroid : this.asteroidTemplate)
88 {
89 if (asteroid.probability >= chance)
90 {
91 to_generate.add(asteroid);
92 }
93 }
94 return to_generate;
95 }
96
97 private void createAsteroid()
98 {
99 List<AsteroidSmall> asteroids_to_create = new ArrayList<AsteroidSmall>();
100 switch (this.selectedRandomStrategy)
101 {
102 case RANDOM_STRATEGY_RANDOM:
103 asteroids_to_create = generateAsteroidsRandom();
104 break;
105 case RANDOM_STRATEGY_GUARANTEED:
106 asteroids_to_create = generateAsteroidsGuaranteed();
107 break;
108 default:
109 break;
110 }
111 if (asteroids_to_create.size() == 0)
112 {
113 return;
114 }
115 //for (int i = 0;i<asteroids_to_create.size();i++)
116 for (AsteroidSmall asteroid : asteroids_to_create)
117 {
118 int myMass = (int)(asteroid.mass + ((generator.nextFloat()*asteroid.massVariability)*asteroid.mass) - asteroid.massVariability*asteroid.mass/2f);
119 int numOres = (int) (myMass*(asteroid.richness + generator.nextFloat()*asteroid.richnessVariability - asteroid.richnessVariability/2f));
120 //String sql = "INSERT INTO asteroids VALUES (NULL, distance, mass, )";
121 String sql = "INSERT INTO asteroids (templateName, distance, mass, numOres, dataseed) VALUES ('"+asteroid.ID+"', "+asteroid.distance+","+myMass+","+numOres+","+generator.nextInt()+")";
122 try
123 {
124 this.stmt.executeUpdate(sql);
125 }
126 catch (SQLException e)
127 {
128 e.printStackTrace();
129 }
130 }
131
132 }
133 void dbCreateTables()
134 {
135 // TODO Create table ONLY if it is does not exists!
136 try {
137 //stmt = c.createStatement();
138 String sql = "CREATE TABLE IF NOT EXISTS asteroids ("
139 + "ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
140 + "templateName varchar(32), "
141 + "numOres int unsigned, "
142 + "distance int unsigned, "//just to filter faster
143 + "mass int unsigned, "
144// + "minLevel int unsigned, "
145// + "richness int unsigned, "
146// + "timeMultiplier float, "
147 + "dataseed int unsigned, "
148 + "created DATETIME NOT NULL DEFAULT (datetime('now','localtime')))";
149 stmt.executeUpdate(sql);
150 //stmt.close();
151 //c.close();
152 } catch (SQLException e) {
153 // TODO Auto-generated catch block
154 e.printStackTrace();
155 }
156
157 }
158 void dbClose()
159 {
160 try {
161 this.stmt.close();
162 } catch (SQLException e) {
163 // TODO Auto-generated catch block
164 e.printStackTrace();
165 }
166 try {
167 this.c.close();
168 } catch (SQLException e) {
169 // TODO Auto-generated catch block
170 e.printStackTrace();
171 }
172 }
173 void dbReconnect()
174 {
175 try {
176 Class.forName("org.sqlite.JDBC");
177 c = DriverManager.getConnection("jdbc:sqlite:config/advRocketry/asteroids.db");
178 } catch ( Exception e ) {
179 System.err.println( e.getClass().getName() + ": " + e.getMessage() );
180 //System.exit(0);
181 }
182 try {
183 this.stmt = this.c.createStatement();
184 } catch (SQLException e) {
185 // TODO Auto-generated catch block
186 e.printStackTrace();
187 }
188 //System.out.println("Opened database successfully");
189 }
190
191 @Override
192 public void start()
193 {
194 System.out.println("THREAD starting");
195 if (this.cfg == null)
196 {
197 System.err.print("You should call set_config() first!");
198 return;
199 }
200 this.dbReconnect();
201 this.dbCreateTables();
202 super.start();
203 System.out.println("THREAD started!");
204 }
205
206 @Override
207 public void run() //Этот метод будет выполнен в побочном потоке
208 {
209 this.init();
210 int dbCheckDelayMsCounter=0;
211 while (true)
212 {
213 if (++dbCheckDelayMsCounter >= dbCheckDelayMs)
214 {
215 dbCheckDelayMsCounter = 0;
216 try {
217 this.check_db();
218 } catch (SQLException e) {
219 // TODO Auto-generated catch block
220 e.printStackTrace();
221 }
222 }
223 try {
224 //System.out.println("[server] thread test"+LocalTime.now().compareTo(LocalTime.parse(parent.getConfig().getStringList("restart_time").get(0))));
225 Thread.sleep(sleepDelayMs);
226 } catch (InterruptedException e) {
227 // TODO Auto-generated catch block
228 e.printStackTrace();
229 //it's ok
230 }
231 }
232 }
233 private int getGeneratedAsteroidsNum() throws SQLException
234 {
235 String str = "SELECT COUNT(1) as cnt FROM asteroids";
236 ResultSet rs = stmt.executeQuery(str);
237 //rs.next();
238 return rs.getInt("cnt");
239
240 }
241 private void check_db() throws SQLException {
242
243 String str = "SELECT seq FROM sqlite_sequence where name = 'asteroids'";
244 try {
245 ResultSet rs = stmt.executeQuery(str);
246 int seq = rs.getInt("seq");
247 //rs.next();
248 System.out.println("seq: "+seq);
249 if ( seq >= DB_SQLITE_SEQ_OFV )
250 {
251 str = "UPDATE sqlite_sequence SET seq=0 WHERE name='asteroids'";
252 stmt.execute(str);
253 str = "DELETE FROM asteroids";
254 stmt.execute(str);
255 System.out.println("table asteroids may be overflowed. Re-creating it.");
256 // this.dbCreateTables();
257 }
258 }
259 catch (SQLException e)
260 {
261 e.printStackTrace();
262 }
263
264 str = "DELETE FROM asteroids WHERE (strftime('%s',datetime('now','localtime')) - strftime('%s', (created))) > mass*"+ASTEROID_ALIVE_TIME_SEC;
265 stmt.execute(str);
266 //=>can be infinity cycle if no template would be in config
267 while (getGeneratedAsteroidsNum() < MAX_DB_ASTEROIDS)
268 {
269 this.createAsteroid();
270 //cnt++;
271 }
272 //System.out.println( "cnt = " + get_num_generated_asteroids() );
273 /*
274 while ( rs.next() ) {
275 System.out.println( "name = " + rs.getString("name") );
276 System.out.println( "created = " + rs.getString("created") );
277 }*/
278 //System.out.println("check_db");
279 }
280
281}
282