Création de la librairie Java PandacubeUtil
Utilisé par PandacubeBungee et PandacubeSpigot
This commit is contained in:
commit
6bc15b24f6
10
.classpath
Normal file
10
.classpath
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="src" path="resources"/>
|
||||||
|
<classpathentry kind="lib" path="lib/BungeeCord-1071.jar" sourcepath="lib/BungeeCord-1071.src.zip"/>
|
||||||
|
<classpathentry kind="lib" path="lib/BungeePerms-3.0-alpha-1_modif.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/spigot-1.8.8.jar" sourcepath="lib/spigot-1.8.8_source.zip"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
convertToBungeePerms.txt
|
17
.project
Normal file
17
.project
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>PandacubeUtil</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
17
make_jar.jardesc
Normal file
17
make_jar.jardesc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<jardesc>
|
||||||
|
<jar path="JavaBungeeSpigotUtil/jar_export/JavaBungeeSpigotUtil-1.0-beta1.jar"/>
|
||||||
|
<options buildIfNeeded="true" compress="true" descriptionLocation="/JavaBungeeSpigotUtil/make_jar.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
|
||||||
|
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
|
||||||
|
<selectedProjects/>
|
||||||
|
<manifest generateManifest="false" manifestLocation="/JavaBungeeSpigotUtil/manifest" manifestVersion="1.0" reuseManifest="true" saveManifest="true" usesManifest="true">
|
||||||
|
<sealing sealJar="false">
|
||||||
|
<packagesToSeal/>
|
||||||
|
<packagesToUnSeal/>
|
||||||
|
</sealing>
|
||||||
|
</manifest>
|
||||||
|
<selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
|
||||||
|
<javaElement handleIdentifier="=JavaBungeeSpigotUtil/resources"/>
|
||||||
|
<javaElement handleIdentifier="=JavaBungeeSpigotUtil/src"/>
|
||||||
|
</selectedElements>
|
||||||
|
</jardesc>
|
4
resources/bungee.yml
Normal file
4
resources/bungee.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
name: PandacubeUtil
|
||||||
|
main: fr.pandacube.java.BungeeMain
|
||||||
|
version: 1.0-beta1
|
||||||
|
author: Marc Baloup (marcbal)
|
4
resources/plugin.yml
Normal file
4
resources/plugin.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
name: PandacubeUtil
|
||||||
|
main: fr.pandacube.java.SpigotMain
|
||||||
|
version: 1.0-beta1
|
||||||
|
author: Marc Baloup (marcbal)
|
175
src/com/earth2me/essentials/utils/DateUtil.java
Normal file
175
src/com/earth2me/essentials/utils/DateUtil.java
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
package com.earth2me.essentials.utils;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
public class DateUtil
|
||||||
|
{
|
||||||
|
public static long parseDateDiff(String time, boolean future) throws Exception
|
||||||
|
{
|
||||||
|
Pattern timePattern = Pattern.compile("(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher m = timePattern.matcher(time);
|
||||||
|
int years = 0;
|
||||||
|
int months = 0;
|
||||||
|
int weeks = 0;
|
||||||
|
int days = 0;
|
||||||
|
int hours = 0;
|
||||||
|
int minutes = 0;
|
||||||
|
int seconds = 0;
|
||||||
|
boolean found = false;
|
||||||
|
while (m.find())
|
||||||
|
{
|
||||||
|
if (m.group() == null || m.group().isEmpty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m.groupCount(); i++)
|
||||||
|
{
|
||||||
|
if (m.group(i) != null && !m.group(i).isEmpty())
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
if (m.group(1) != null && !m.group(1).isEmpty())
|
||||||
|
{
|
||||||
|
years = Integer.parseInt(m.group(1));
|
||||||
|
}
|
||||||
|
if (m.group(2) != null && !m.group(2).isEmpty())
|
||||||
|
{
|
||||||
|
months = Integer.parseInt(m.group(2));
|
||||||
|
}
|
||||||
|
if (m.group(3) != null && !m.group(3).isEmpty())
|
||||||
|
{
|
||||||
|
weeks = Integer.parseInt(m.group(3));
|
||||||
|
}
|
||||||
|
if (m.group(4) != null && !m.group(4).isEmpty())
|
||||||
|
{
|
||||||
|
days = Integer.parseInt(m.group(4));
|
||||||
|
}
|
||||||
|
if (m.group(5) != null && !m.group(5).isEmpty())
|
||||||
|
{
|
||||||
|
hours = Integer.parseInt(m.group(5));
|
||||||
|
}
|
||||||
|
if (m.group(6) != null && !m.group(6).isEmpty())
|
||||||
|
{
|
||||||
|
minutes = Integer.parseInt(m.group(6));
|
||||||
|
}
|
||||||
|
if (m.group(7) != null && !m.group(7).isEmpty())
|
||||||
|
{
|
||||||
|
seconds = Integer.parseInt(m.group(7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
throw new Exception("Format de durée invalide");
|
||||||
|
}
|
||||||
|
Calendar c = new GregorianCalendar();
|
||||||
|
if (years > 0)
|
||||||
|
{
|
||||||
|
c.add(Calendar.YEAR, years * (future ? 1 : -1));
|
||||||
|
}
|
||||||
|
if (months > 0)
|
||||||
|
{
|
||||||
|
c.add(Calendar.MONTH, months * (future ? 1 : -1));
|
||||||
|
}
|
||||||
|
if (weeks > 0)
|
||||||
|
{
|
||||||
|
c.add(Calendar.WEEK_OF_YEAR, weeks * (future ? 1 : -1));
|
||||||
|
}
|
||||||
|
if (days > 0)
|
||||||
|
{
|
||||||
|
c.add(Calendar.DAY_OF_MONTH, days * (future ? 1 : -1));
|
||||||
|
}
|
||||||
|
if (hours > 0)
|
||||||
|
{
|
||||||
|
c.add(Calendar.HOUR_OF_DAY, hours * (future ? 1 : -1));
|
||||||
|
}
|
||||||
|
if (minutes > 0)
|
||||||
|
{
|
||||||
|
c.add(Calendar.MINUTE, minutes * (future ? 1 : -1));
|
||||||
|
}
|
||||||
|
if (seconds > 0)
|
||||||
|
{
|
||||||
|
c.add(Calendar.SECOND, seconds * (future ? 1 : -1));
|
||||||
|
}
|
||||||
|
Calendar max = new GregorianCalendar();
|
||||||
|
max.add(Calendar.YEAR, 10);
|
||||||
|
if (c.after(max))
|
||||||
|
{
|
||||||
|
return max.getTimeInMillis();
|
||||||
|
}
|
||||||
|
return c.getTimeInMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dateDiff(int type, Calendar fromDate, Calendar toDate, boolean future)
|
||||||
|
{
|
||||||
|
int diff = 0;
|
||||||
|
long savedDate = fromDate.getTimeInMillis();
|
||||||
|
while ((future && !fromDate.after(toDate)) || (!future && !fromDate.before(toDate)))
|
||||||
|
{
|
||||||
|
savedDate = fromDate.getTimeInMillis();
|
||||||
|
fromDate.add(type, future ? 1 : -1);
|
||||||
|
diff++;
|
||||||
|
}
|
||||||
|
diff--;
|
||||||
|
fromDate.setTimeInMillis(savedDate);
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatDateDiff(long date)
|
||||||
|
{
|
||||||
|
Calendar c = new GregorianCalendar();
|
||||||
|
c.setTimeInMillis(date);
|
||||||
|
Calendar now = new GregorianCalendar();
|
||||||
|
return DateUtil.formatDateDiff(now, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatDateDiff(Calendar fromDate, Calendar toDate)
|
||||||
|
{
|
||||||
|
boolean future = false;
|
||||||
|
if (toDate.equals(fromDate))
|
||||||
|
{
|
||||||
|
return "now";
|
||||||
|
}
|
||||||
|
if (toDate.after(fromDate))
|
||||||
|
{
|
||||||
|
future = true;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int[] types = new int[]
|
||||||
|
{
|
||||||
|
Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND
|
||||||
|
};
|
||||||
|
String[] names = new String[]
|
||||||
|
{
|
||||||
|
"year", "years", "month", "months", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds"
|
||||||
|
};
|
||||||
|
int accuracy = 0;
|
||||||
|
for (int i = 0; i < types.length; i++)
|
||||||
|
{
|
||||||
|
if (accuracy > 2)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int diff = dateDiff(types[i], fromDate, toDate, future);
|
||||||
|
if (diff > 0)
|
||||||
|
{
|
||||||
|
accuracy++;
|
||||||
|
sb.append(" ").append(diff).append(" ").append(names[i * 2 + (diff > 1 ? 1 : 0)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sb.length() == 0)
|
||||||
|
{
|
||||||
|
return "now";
|
||||||
|
}
|
||||||
|
return sb.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
290
src/com/luckycatlabs/sunrisesunset/SunriseSunsetCalculator.java
Normal file
290
src/com/luckycatlabs/sunrisesunset/SunriseSunsetCalculator.java
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009 Mike Reedell / LuckyCatLabs.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.luckycatlabs.sunrisesunset;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import com.luckycatlabs.sunrisesunset.calculator.SolarEventCalculator;
|
||||||
|
import com.luckycatlabs.sunrisesunset.dto.Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public interface for getting the various types of sunrise/sunset.
|
||||||
|
*/
|
||||||
|
public class SunriseSunsetCalculator {
|
||||||
|
|
||||||
|
private Location location;
|
||||||
|
|
||||||
|
private SolarEventCalculator calculator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new <code>SunriseSunsetCalculator</code> with the given <code>Location</code>
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* <code>Location</code> object containing the Latitude/Longitude of the location to compute
|
||||||
|
* the sunrise/sunset for.
|
||||||
|
* @param timeZoneIdentifier
|
||||||
|
* String identifier for the timezone to compute the sunrise/sunset times in. In the form
|
||||||
|
* "America/New_York". Please see the zi directory under the JDK installation for supported
|
||||||
|
* time zones.
|
||||||
|
*/
|
||||||
|
public SunriseSunsetCalculator(Location location, String timeZoneIdentifier) {
|
||||||
|
this.location = location;
|
||||||
|
this.calculator = new SolarEventCalculator(location, timeZoneIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new <code>SunriseSunsetCalculator</code> with the given <code>Location</code>
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* <code>Location</code> object containing the Latitude/Longitude of the location to compute
|
||||||
|
* the sunrise/sunset for.
|
||||||
|
* @param timeZone
|
||||||
|
* timezone to compute the sunrise/sunset times in.
|
||||||
|
*/
|
||||||
|
public SunriseSunsetCalculator(Location location, TimeZone timeZone) {
|
||||||
|
this.location = location;
|
||||||
|
this.calculator = new SolarEventCalculator(location, timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the astronomical (108deg) sunrise for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the astronomical sunrise for.
|
||||||
|
* @return the astronomical sunrise time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getAstronomicalSunriseForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseTime(Zenith.ASTRONOMICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the astronomical (108deg) sunrise for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the astronomical sunrise for.
|
||||||
|
* @return the astronomical sunrise time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getAstronomicalSunriseCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseCalendar(Zenith.ASTRONOMICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the astronomical (108deg) sunset for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the astronomical sunset for.
|
||||||
|
* @return the astronomical sunset time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getAstronomicalSunsetForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetTime(Zenith.ASTRONOMICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the astronomical (108deg) sunset for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the astronomical sunset for.
|
||||||
|
* @return the astronomical sunset time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getAstronomicalSunsetCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetCalendar(Zenith.ASTRONOMICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nautical (102deg) sunrise for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the nautical sunrise for.
|
||||||
|
* @return the nautical sunrise time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getNauticalSunriseForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseTime(Zenith.NAUTICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nautical (102deg) sunrise for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the nautical sunrise for.
|
||||||
|
* @return the nautical sunrise time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getNauticalSunriseCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseCalendar(Zenith.NAUTICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nautical (102deg) sunset for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the nautical sunset for.
|
||||||
|
* @return the nautical sunset time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getNauticalSunsetForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetTime(Zenith.NAUTICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nautical (102deg) sunset for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the nautical sunset for.
|
||||||
|
* @return the nautical sunset time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getNauticalSunsetCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetCalendar(Zenith.NAUTICAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the civil sunrise (twilight, 96deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the civil sunrise for.
|
||||||
|
* @return the civil sunrise time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getCivilSunriseForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseTime(Zenith.CIVIL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the civil sunrise (twilight, 96deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the civil sunrise for.
|
||||||
|
* @return the civil sunrise time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getCivilSunriseCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseCalendar(Zenith.CIVIL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the civil sunset (twilight, 96deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the civil sunset for.
|
||||||
|
* @return the civil sunset time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getCivilSunsetForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetTime(Zenith.CIVIL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the civil sunset (twilight, 96deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the civil sunset for.
|
||||||
|
* @return the civil sunset time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getCivilSunsetCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetCalendar(Zenith.CIVIL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the official sunrise (90deg 50', 90.8333deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the official sunrise for.
|
||||||
|
* @return the official sunrise time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getOfficialSunriseForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseTime(Zenith.OFFICIAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the official sunrise (90deg 50', 90.8333deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the official sunrise for.
|
||||||
|
* @return the official sunrise time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getOfficialSunriseCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunriseCalendar(Zenith.OFFICIAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the official sunrise (90deg 50', 90.8333deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the official sunset for.
|
||||||
|
* @return the official sunset time in HH:MM (24-hour clock) form.
|
||||||
|
*/
|
||||||
|
public String getOfficialSunsetForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetTime(Zenith.OFFICIAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the official sunrise (90deg 50', 90.8333deg) for the given date.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the official sunset for.
|
||||||
|
* @return the official sunset time as a Calendar
|
||||||
|
*/
|
||||||
|
public Calendar getOfficialSunsetCalendarForDate(Calendar date) {
|
||||||
|
return calculator.computeSunsetCalendar(Zenith.OFFICIAL, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the sunrise for an arbitrary declination.
|
||||||
|
*
|
||||||
|
* @param latitude
|
||||||
|
* @param longitude
|
||||||
|
* Coordinates for the location to compute the sunrise/sunset for.
|
||||||
|
* @param timeZone
|
||||||
|
* timezone to compute the sunrise/sunset times in.
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the official sunset for.
|
||||||
|
* @param degrees
|
||||||
|
* Angle under the horizon for which to compute sunrise. For example, "civil sunrise"
|
||||||
|
* corresponds to 6 degrees.
|
||||||
|
* @return the requested sunset time as a <code>Calendar</code> object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Calendar getSunrise(double latitude, double longitude, TimeZone timeZone, Calendar date, double degrees) {
|
||||||
|
SolarEventCalculator solarEventCalculator = new SolarEventCalculator(new Location(latitude, longitude), timeZone);
|
||||||
|
return solarEventCalculator.computeSunriseCalendar(new Zenith(90 - degrees), date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the sunset for an arbitrary declination.
|
||||||
|
*
|
||||||
|
* @param latitude
|
||||||
|
* @param longitude
|
||||||
|
* Coordinates for the location to compute the sunrise/sunset for.
|
||||||
|
* @param timeZone
|
||||||
|
* timezone to compute the sunrise/sunset times in.
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object containing the date to compute the official sunset for.
|
||||||
|
* @param degrees
|
||||||
|
* Angle under the horizon for which to compute sunrise. For example, "civil sunset"
|
||||||
|
* corresponds to 6 degrees.
|
||||||
|
* @return the requested sunset time as a <code>Calendar</code> object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Calendar getSunset(double latitude, double longitude, TimeZone timeZone, Calendar date, double degrees) {
|
||||||
|
SolarEventCalculator solarEventCalculator = new SolarEventCalculator(new Location(latitude, longitude), timeZone);
|
||||||
|
return solarEventCalculator.computeSunsetCalendar(new Zenith(90 - degrees), date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location where the sunrise/sunset is calculated for.
|
||||||
|
*
|
||||||
|
* @return <code>Location</code> object representing the location of the computed sunrise/sunset.
|
||||||
|
*/
|
||||||
|
public Location getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
}
|
46
src/com/luckycatlabs/sunrisesunset/Zenith.java
Normal file
46
src/com/luckycatlabs/sunrisesunset/Zenith.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009 Mike Reedell / LuckyCatLabs.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.luckycatlabs.sunrisesunset;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the solar declination used in computing the sunrise/sunset.
|
||||||
|
*/
|
||||||
|
public class Zenith {
|
||||||
|
/** Astronomical sunrise/set is when the sun is 18 degrees below the horizon. */
|
||||||
|
public static final Zenith ASTRONOMICAL = new Zenith(108);
|
||||||
|
|
||||||
|
/** Nautical sunrise/set is when the sun is 12 degrees below the horizon. */
|
||||||
|
public static final Zenith NAUTICAL = new Zenith(102);
|
||||||
|
|
||||||
|
/** Civil sunrise/set (dawn/dusk) is when the sun is 6 degrees below the horizon. */
|
||||||
|
public static final Zenith CIVIL = new Zenith(96);
|
||||||
|
|
||||||
|
/** Official sunrise/set is when the sun is 50' below the horizon. */
|
||||||
|
public static final Zenith OFFICIAL = new Zenith(90.8333);
|
||||||
|
|
||||||
|
private final BigDecimal degrees;
|
||||||
|
|
||||||
|
public Zenith(double degrees) {
|
||||||
|
this.degrees = BigDecimal.valueOf(degrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal degrees() {
|
||||||
|
return degrees;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009 Mike Reedell / LuckyCatLabs.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.luckycatlabs.sunrisesunset.calculator;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import com.luckycatlabs.sunrisesunset.Zenith;
|
||||||
|
import com.luckycatlabs.sunrisesunset.dto.Location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent class of the Sunrise and Sunset calculator classes.
|
||||||
|
*/
|
||||||
|
public class SolarEventCalculator {
|
||||||
|
final private Location location;
|
||||||
|
final private TimeZone timeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new <code>SolarEventCalculator</code> using the given parameters.
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* <code>Location</code> of the place where the solar event should be calculated from.
|
||||||
|
* @param timeZoneIdentifier
|
||||||
|
* time zone identifier of the timezone of the location parameter. For example,
|
||||||
|
* "America/New_York".
|
||||||
|
*/
|
||||||
|
public SolarEventCalculator(Location location, String timeZoneIdentifier) {
|
||||||
|
this.location = location;
|
||||||
|
this.timeZone = TimeZone.getTimeZone(timeZoneIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new <code>SolarEventCalculator</code> using the given parameters.
|
||||||
|
*
|
||||||
|
* @param location
|
||||||
|
* <code>Location</code> of the place where the solar event should be calculated from.
|
||||||
|
* @param timeZone
|
||||||
|
* timezone of the location parameter.
|
||||||
|
*/
|
||||||
|
public SolarEventCalculator(Location location, TimeZone timeZone) {
|
||||||
|
this.location = location;
|
||||||
|
this.timeZone = timeZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the sunrise time for the given zenith at the given date.
|
||||||
|
*
|
||||||
|
* @param solarZenith
|
||||||
|
* <code>Zenith</code> enum corresponding to the type of sunrise to compute.
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object representing the date to compute the sunrise for.
|
||||||
|
* @return the sunrise time, in HH:MM format (24-hour clock), 00:00 if the sun does not rise on the given
|
||||||
|
* date.
|
||||||
|
*/
|
||||||
|
public String computeSunriseTime(Zenith solarZenith, Calendar date) {
|
||||||
|
return getLocalTimeAsString(computeSolarEventTime(solarZenith, date, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the sunrise time for the given zenith at the given date.
|
||||||
|
*
|
||||||
|
* @param solarZenith
|
||||||
|
* <code>Zenith</code> enum corresponding to the type of sunrise to compute.
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object representing the date to compute the sunrise for.
|
||||||
|
* @return the sunrise time as a calendar or null for no sunrise
|
||||||
|
*/
|
||||||
|
public Calendar computeSunriseCalendar(Zenith solarZenith, Calendar date) {
|
||||||
|
return getLocalTimeAsCalendar(computeSolarEventTime(solarZenith, date, true), date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the sunset time for the given zenith at the given date.
|
||||||
|
*
|
||||||
|
* @param solarZenith
|
||||||
|
* <code>Zenith</code> enum corresponding to the type of sunset to compute.
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object representing the date to compute the sunset for.
|
||||||
|
* @return the sunset time, in HH:MM format (24-hour clock), 00:00 if the sun does not set on the given
|
||||||
|
* date.
|
||||||
|
*/
|
||||||
|
public String computeSunsetTime(Zenith solarZenith, Calendar date) {
|
||||||
|
return getLocalTimeAsString(computeSolarEventTime(solarZenith, date, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the sunset time for the given zenith at the given date.
|
||||||
|
*
|
||||||
|
* @param solarZenith
|
||||||
|
* <code>Zenith</code> enum corresponding to the type of sunset to compute.
|
||||||
|
* @param date
|
||||||
|
* <code>Calendar</code> object representing the date to compute the sunset for.
|
||||||
|
* @return the sunset time as a Calendar or null for no sunset.
|
||||||
|
*/
|
||||||
|
public Calendar computeSunsetCalendar(Zenith solarZenith, Calendar date) {
|
||||||
|
return getLocalTimeAsCalendar(computeSolarEventTime(solarZenith, date, false), date);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal computeSolarEventTime(Zenith solarZenith, Calendar date, boolean isSunrise) {
|
||||||
|
date.setTimeZone(this.timeZone);
|
||||||
|
BigDecimal longitudeHour = getLongitudeHour(date, isSunrise);
|
||||||
|
|
||||||
|
BigDecimal meanAnomaly = getMeanAnomaly(longitudeHour);
|
||||||
|
BigDecimal sunTrueLong = getSunTrueLongitude(meanAnomaly);
|
||||||
|
BigDecimal cosineSunLocalHour = getCosineSunLocalHour(sunTrueLong, solarZenith);
|
||||||
|
if ((cosineSunLocalHour.doubleValue() < -1.0) || (cosineSunLocalHour.doubleValue() > 1.0)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal sunLocalHour = getSunLocalHour(cosineSunLocalHour, isSunrise);
|
||||||
|
BigDecimal localMeanTime = getLocalMeanTime(sunTrueLong, longitudeHour, sunLocalHour);
|
||||||
|
BigDecimal localTime = getLocalTime(localMeanTime, date);
|
||||||
|
return localTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the base longitude hour, lngHour in the algorithm.
|
||||||
|
*
|
||||||
|
* @return the longitude of the location of the solar event divided by 15 (deg/hour), in
|
||||||
|
* <code>BigDecimal</code> form.
|
||||||
|
*/
|
||||||
|
private BigDecimal getBaseLongitudeHour() {
|
||||||
|
return divideBy(location.getLongitude(), BigDecimal.valueOf(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the longitude time, t in the algorithm.
|
||||||
|
*
|
||||||
|
* @return longitudinal time in <code>BigDecimal</code> form.
|
||||||
|
*/
|
||||||
|
private BigDecimal getLongitudeHour(Calendar date, Boolean isSunrise) {
|
||||||
|
int offset = 18;
|
||||||
|
if (isSunrise) {
|
||||||
|
offset = 6;
|
||||||
|
}
|
||||||
|
BigDecimal dividend = BigDecimal.valueOf(offset).subtract(getBaseLongitudeHour());
|
||||||
|
BigDecimal addend = divideBy(dividend, BigDecimal.valueOf(24));
|
||||||
|
BigDecimal longHour = getDayOfYear(date).add(addend);
|
||||||
|
return setScale(longHour);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the mean anomaly of the Sun, M in the algorithm.
|
||||||
|
*
|
||||||
|
* @return the suns mean anomaly, M, in <code>BigDecimal</code> form.
|
||||||
|
*/
|
||||||
|
private BigDecimal getMeanAnomaly(BigDecimal longitudeHour) {
|
||||||
|
BigDecimal meanAnomaly = multiplyBy(new BigDecimal("0.9856"), longitudeHour).subtract(new BigDecimal("3.289"));
|
||||||
|
return setScale(meanAnomaly);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the true longitude of the sun, L in the algorithm, at the given location, adjusted to fit in
|
||||||
|
* the range [0-360].
|
||||||
|
*
|
||||||
|
* @param meanAnomaly
|
||||||
|
* the suns mean anomaly.
|
||||||
|
* @return the suns true longitude, in <code>BigDecimal</code> form.
|
||||||
|
*/
|
||||||
|
private BigDecimal getSunTrueLongitude(BigDecimal meanAnomaly) {
|
||||||
|
BigDecimal sinMeanAnomaly = new BigDecimal(Math.sin(convertDegreesToRadians(meanAnomaly).doubleValue()));
|
||||||
|
BigDecimal sinDoubleMeanAnomaly = new BigDecimal(Math.sin(multiplyBy(convertDegreesToRadians(meanAnomaly), BigDecimal.valueOf(2))
|
||||||
|
.doubleValue()));
|
||||||
|
|
||||||
|
BigDecimal firstPart = meanAnomaly.add(multiplyBy(sinMeanAnomaly, new BigDecimal("1.916")));
|
||||||
|
BigDecimal secondPart = multiplyBy(sinDoubleMeanAnomaly, new BigDecimal("0.020")).add(new BigDecimal("282.634"));
|
||||||
|
BigDecimal trueLongitude = firstPart.add(secondPart);
|
||||||
|
|
||||||
|
if (trueLongitude.doubleValue() > 360) {
|
||||||
|
trueLongitude = trueLongitude.subtract(BigDecimal.valueOf(360));
|
||||||
|
}
|
||||||
|
return setScale(trueLongitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the suns right ascension, RA in the algorithm, adjusting for the quadrant of L and turning it
|
||||||
|
* into degree-hours. Will be in the range [0,360].
|
||||||
|
*
|
||||||
|
* @param sunTrueLong
|
||||||
|
* Suns true longitude, in <code>BigDecimal</code>
|
||||||
|
* @return suns right ascension in degree-hours, in <code>BigDecimal</code> form.
|
||||||
|
*/
|
||||||
|
private BigDecimal getRightAscension(BigDecimal sunTrueLong) {
|
||||||
|
BigDecimal tanL = new BigDecimal(Math.tan(convertDegreesToRadians(sunTrueLong).doubleValue()));
|
||||||
|
|
||||||
|
BigDecimal innerParens = multiplyBy(convertRadiansToDegrees(tanL), new BigDecimal("0.91764"));
|
||||||
|
BigDecimal rightAscension = new BigDecimal(Math.atan(convertDegreesToRadians(innerParens).doubleValue()));
|
||||||
|
rightAscension = setScale(convertRadiansToDegrees(rightAscension));
|
||||||
|
|
||||||
|
if (rightAscension.doubleValue() < 0) {
|
||||||
|
rightAscension = rightAscension.add(BigDecimal.valueOf(360));
|
||||||
|
} else if (rightAscension.doubleValue() > 360) {
|
||||||
|
rightAscension = rightAscension.subtract(BigDecimal.valueOf(360));
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal ninety = BigDecimal.valueOf(90);
|
||||||
|
BigDecimal longitudeQuadrant = sunTrueLong.divide(ninety, 0, RoundingMode.FLOOR);
|
||||||
|
longitudeQuadrant = longitudeQuadrant.multiply(ninety);
|
||||||
|
|
||||||
|
BigDecimal rightAscensionQuadrant = rightAscension.divide(ninety, 0, RoundingMode.FLOOR);
|
||||||
|
rightAscensionQuadrant = rightAscensionQuadrant.multiply(ninety);
|
||||||
|
|
||||||
|
BigDecimal augend = longitudeQuadrant.subtract(rightAscensionQuadrant);
|
||||||
|
return divideBy(rightAscension.add(augend), BigDecimal.valueOf(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getCosineSunLocalHour(BigDecimal sunTrueLong, Zenith zenith) {
|
||||||
|
BigDecimal sinSunDeclination = getSinOfSunDeclination(sunTrueLong);
|
||||||
|
BigDecimal cosineSunDeclination = getCosineOfSunDeclination(sinSunDeclination);
|
||||||
|
|
||||||
|
BigDecimal zenithInRads = convertDegreesToRadians(zenith.degrees());
|
||||||
|
BigDecimal cosineZenith = BigDecimal.valueOf(Math.cos(zenithInRads.doubleValue()));
|
||||||
|
BigDecimal sinLatitude = BigDecimal.valueOf(Math.sin(convertDegreesToRadians(location.getLatitude()).doubleValue()));
|
||||||
|
BigDecimal cosLatitude = BigDecimal.valueOf(Math.cos(convertDegreesToRadians(location.getLatitude()).doubleValue()));
|
||||||
|
|
||||||
|
BigDecimal sinDeclinationTimesSinLat = sinSunDeclination.multiply(sinLatitude);
|
||||||
|
BigDecimal dividend = cosineZenith.subtract(sinDeclinationTimesSinLat);
|
||||||
|
BigDecimal divisor = cosineSunDeclination.multiply(cosLatitude);
|
||||||
|
|
||||||
|
return setScale(divideBy(dividend, divisor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getSinOfSunDeclination(BigDecimal sunTrueLong) {
|
||||||
|
BigDecimal sinTrueLongitude = BigDecimal.valueOf(Math.sin(convertDegreesToRadians(sunTrueLong).doubleValue()));
|
||||||
|
BigDecimal sinOfDeclination = sinTrueLongitude.multiply(new BigDecimal("0.39782"));
|
||||||
|
return setScale(sinOfDeclination);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getCosineOfSunDeclination(BigDecimal sinSunDeclination) {
|
||||||
|
BigDecimal arcSinOfSinDeclination = BigDecimal.valueOf(Math.asin(sinSunDeclination.doubleValue()));
|
||||||
|
BigDecimal cosDeclination = BigDecimal.valueOf(Math.cos(arcSinOfSinDeclination.doubleValue()));
|
||||||
|
return setScale(cosDeclination);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getSunLocalHour(BigDecimal cosineSunLocalHour, Boolean isSunrise) {
|
||||||
|
BigDecimal arcCosineOfCosineHourAngle = getArcCosineFor(cosineSunLocalHour);
|
||||||
|
BigDecimal localHour = convertRadiansToDegrees(arcCosineOfCosineHourAngle);
|
||||||
|
if (isSunrise) {
|
||||||
|
localHour = BigDecimal.valueOf(360).subtract(localHour);
|
||||||
|
}
|
||||||
|
return divideBy(localHour, BigDecimal.valueOf(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getLocalMeanTime(BigDecimal sunTrueLong, BigDecimal longitudeHour, BigDecimal sunLocalHour) {
|
||||||
|
BigDecimal rightAscension = this.getRightAscension(sunTrueLong);
|
||||||
|
BigDecimal innerParens = longitudeHour.multiply(new BigDecimal("0.06571"));
|
||||||
|
BigDecimal localMeanTime = sunLocalHour.add(rightAscension).subtract(innerParens);
|
||||||
|
localMeanTime = localMeanTime.subtract(new BigDecimal("6.622"));
|
||||||
|
|
||||||
|
if (localMeanTime.doubleValue() < 0) {
|
||||||
|
localMeanTime = localMeanTime.add(BigDecimal.valueOf(24));
|
||||||
|
} else if (localMeanTime.doubleValue() > 24) {
|
||||||
|
localMeanTime = localMeanTime.subtract(BigDecimal.valueOf(24));
|
||||||
|
}
|
||||||
|
return setScale(localMeanTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getLocalTime(BigDecimal localMeanTime, Calendar date) {
|
||||||
|
BigDecimal utcTime = localMeanTime.subtract(getBaseLongitudeHour());
|
||||||
|
BigDecimal utcOffSet = getUTCOffSet(date);
|
||||||
|
BigDecimal utcOffSetTime = utcTime.add(utcOffSet);
|
||||||
|
return adjustForDST(utcOffSetTime, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal adjustForDST(BigDecimal localMeanTime, Calendar date) {
|
||||||
|
BigDecimal localTime = localMeanTime;
|
||||||
|
if (timeZone.inDaylightTime(date.getTime())) {
|
||||||
|
localTime = localTime.add(BigDecimal.ONE);
|
||||||
|
}
|
||||||
|
if (localTime.doubleValue() > 24.0) {
|
||||||
|
localTime = localTime.subtract(BigDecimal.valueOf(24));
|
||||||
|
}
|
||||||
|
return localTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the local rise/set time in the form HH:MM.
|
||||||
|
*
|
||||||
|
* @param localTime
|
||||||
|
* <code>BigDecimal</code> representation of the local rise/set time.
|
||||||
|
* @return <code>String</code> representation of the local rise/set time in HH:MM format.
|
||||||
|
*/
|
||||||
|
private String getLocalTimeAsString(BigDecimal localTimeParam) {
|
||||||
|
if (localTimeParam == null) {
|
||||||
|
return "99:99";
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal localTime = localTimeParam;
|
||||||
|
if (localTime.compareTo(BigDecimal.ZERO) == -1) {
|
||||||
|
localTime = localTime.add(BigDecimal.valueOf(24.0D));
|
||||||
|
}
|
||||||
|
String[] timeComponents = localTime.toPlainString().split("\\.");
|
||||||
|
int hour = Integer.parseInt(timeComponents[0]);
|
||||||
|
|
||||||
|
BigDecimal minutes = new BigDecimal("0." + timeComponents[1]);
|
||||||
|
minutes = minutes.multiply(BigDecimal.valueOf(60)).setScale(0, RoundingMode.HALF_EVEN);
|
||||||
|
if (minutes.intValue() == 60) {
|
||||||
|
minutes = BigDecimal.ZERO;
|
||||||
|
hour += 1;
|
||||||
|
}
|
||||||
|
if (hour == 24) {
|
||||||
|
hour = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
String minuteString = minutes.intValue() < 10 ? "0" + minutes.toPlainString() : minutes.toPlainString();
|
||||||
|
String hourString = (hour < 10) ? "0" + String.valueOf(hour) : String.valueOf(hour);
|
||||||
|
return hourString + ":" + minuteString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the local rise/set time in the form HH:MM.
|
||||||
|
*
|
||||||
|
* @param localTimeParam
|
||||||
|
* <code>BigDecimal</code> representation of the local rise/set time.
|
||||||
|
* @return <code>Calendar</code> representation of the local time as a calendar, or null for none.
|
||||||
|
*/
|
||||||
|
protected Calendar getLocalTimeAsCalendar(BigDecimal localTimeParam, Calendar date) {
|
||||||
|
if (localTimeParam == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a clone of the input calendar so we get locale/timezone information.
|
||||||
|
Calendar resultTime = (Calendar) date.clone();
|
||||||
|
|
||||||
|
BigDecimal localTime = localTimeParam;
|
||||||
|
if (localTime.compareTo(BigDecimal.ZERO) == -1) {
|
||||||
|
localTime = localTime.add(BigDecimal.valueOf(24.0D));
|
||||||
|
resultTime.add(Calendar.HOUR_OF_DAY, -24);
|
||||||
|
}
|
||||||
|
String[] timeComponents = localTime.toPlainString().split("\\.");
|
||||||
|
int hour = Integer.parseInt(timeComponents[0]);
|
||||||
|
|
||||||
|
BigDecimal minutes = new BigDecimal("0." + timeComponents[1]);
|
||||||
|
minutes = minutes.multiply(BigDecimal.valueOf(60)).setScale(0, RoundingMode.HALF_EVEN);
|
||||||
|
if (minutes.intValue() == 60) {
|
||||||
|
minutes = BigDecimal.ZERO;
|
||||||
|
hour += 1;
|
||||||
|
}
|
||||||
|
if (hour == 24) {
|
||||||
|
hour = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the local time
|
||||||
|
resultTime.set(Calendar.HOUR_OF_DAY, hour);
|
||||||
|
resultTime.set(Calendar.MINUTE, minutes.intValue());
|
||||||
|
resultTime.set(Calendar.SECOND, 0);
|
||||||
|
resultTime.set(Calendar.MILLISECOND, 0);
|
||||||
|
resultTime.setTimeZone(date.getTimeZone());
|
||||||
|
|
||||||
|
return resultTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ******* UTILITY METHODS (Should probably go somewhere else. ***************** */
|
||||||
|
|
||||||
|
private BigDecimal getDayOfYear(Calendar date) {
|
||||||
|
return new BigDecimal(date.get(Calendar.DAY_OF_YEAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getUTCOffSet(Calendar date) {
|
||||||
|
BigDecimal offSetInMillis = new BigDecimal(date.get(Calendar.ZONE_OFFSET));
|
||||||
|
BigDecimal offSet = offSetInMillis.divide(new BigDecimal(3600000), new MathContext(2));
|
||||||
|
return offSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getArcCosineFor(BigDecimal radians) {
|
||||||
|
BigDecimal arcCosine = BigDecimal.valueOf(Math.acos(radians.doubleValue()));
|
||||||
|
return setScale(arcCosine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal convertRadiansToDegrees(BigDecimal radians) {
|
||||||
|
return multiplyBy(radians, new BigDecimal(180 / Math.PI));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal convertDegreesToRadians(BigDecimal degrees) {
|
||||||
|
return multiplyBy(degrees, BigDecimal.valueOf(Math.PI / 180.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal multiplyBy(BigDecimal multiplicand, BigDecimal multiplier) {
|
||||||
|
return setScale(multiplicand.multiply(multiplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal divideBy(BigDecimal dividend, BigDecimal divisor) {
|
||||||
|
return dividend.divide(divisor, 4, RoundingMode.HALF_EVEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal setScale(BigDecimal number) {
|
||||||
|
return number.setScale(4, RoundingMode.HALF_EVEN);
|
||||||
|
}
|
||||||
|
}
|
93
src/com/luckycatlabs/sunrisesunset/dto/Location.java
Normal file
93
src/com/luckycatlabs/sunrisesunset/dto/Location.java
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008-2009 Mike Reedell / LuckyCatLabs.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.luckycatlabs.sunrisesunset.dto;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple VO class to store latitude/longitude information.
|
||||||
|
*/
|
||||||
|
public class Location {
|
||||||
|
private BigDecimal latitude;
|
||||||
|
private BigDecimal longitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>Location</code> with the given parameters.
|
||||||
|
*
|
||||||
|
* @param latitude
|
||||||
|
* the latitude, in degrees, of this location. North latitude is positive, south negative.
|
||||||
|
* @param longitude
|
||||||
|
* the longitude, in degrees of this location. East longitude is positive, west negative.
|
||||||
|
*/
|
||||||
|
public Location(String latitude, String longitude) {
|
||||||
|
this.latitude = new BigDecimal(latitude);
|
||||||
|
this.longitude = new BigDecimal(longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>Location</code> with the given parameters.
|
||||||
|
*
|
||||||
|
* @param latitude
|
||||||
|
* the latitude, in degrees, of this location. North latitude is positive, south negative.
|
||||||
|
* @param longitude
|
||||||
|
* the longitude, in degrees, of this location. East longitude is positive, east negative.
|
||||||
|
*/
|
||||||
|
public Location(double latitude, double longitude) {
|
||||||
|
this.latitude = new BigDecimal(latitude);
|
||||||
|
this.longitude = new BigDecimal(longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the latitude
|
||||||
|
*/
|
||||||
|
public BigDecimal getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the longitude
|
||||||
|
*/
|
||||||
|
public BigDecimal getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the coordinates of the location object.
|
||||||
|
*
|
||||||
|
* @param latitude
|
||||||
|
* the latitude, in degrees, of this location. North latitude is positive, south negative.
|
||||||
|
* @param longitude
|
||||||
|
* the longitude, in degrees, of this location. East longitude is positive, east negative.
|
||||||
|
*/
|
||||||
|
public void setLocation(String latitude, String longitude) {
|
||||||
|
this.latitude = new BigDecimal(latitude);
|
||||||
|
this.longitude = new BigDecimal(longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the coordinates of the location object.
|
||||||
|
*
|
||||||
|
* @param latitude
|
||||||
|
* the latitude, in degrees, of this location. North latitude is positive, south negative.
|
||||||
|
* @param longitude
|
||||||
|
* the longitude, in degrees, of this location. East longitude is positive, east negative.
|
||||||
|
*/
|
||||||
|
public void setLocation(double latitude, double longitude) {
|
||||||
|
this.latitude = new BigDecimal(latitude);
|
||||||
|
this.longitude = new BigDecimal(longitude);
|
||||||
|
}
|
||||||
|
}
|
11
src/fr/pandacube/java/BungeeMain.java
Normal file
11
src/fr/pandacube/java/BungeeMain.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package fr.pandacube.java;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
|
||||||
|
public class BungeeMain extends Plugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
12
src/fr/pandacube/java/SpigotMain.java
Normal file
12
src/fr/pandacube/java/SpigotMain.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package fr.pandacube.java;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class SpigotMain extends JavaPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package fr.pandacube.java.external_tools;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ConvertToSQLBungeePerms {
|
||||||
|
public static void main(String[] ç) throws Exception {
|
||||||
|
|
||||||
|
List<String> content = getFileLines(true, false, true, new File("convertToBungeePerms.txt"));
|
||||||
|
FileOutputStream output = new FileOutputStream(new File("output.sql"));
|
||||||
|
|
||||||
|
|
||||||
|
String currentSQLFormat = null;
|
||||||
|
|
||||||
|
|
||||||
|
for (String line : content) {
|
||||||
|
|
||||||
|
if (line.startsWith("#sql:"))
|
||||||
|
currentSQLFormat = line.substring("#sql:".length());
|
||||||
|
else
|
||||||
|
output.write(currentSQLFormat.replace("%%%perm%%%", line).concat("\n").getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne toutes les lignes d'un fichier donné
|
||||||
|
* @param ignoreEmpty <code>true</code> si on doit ignorer les lignes vides
|
||||||
|
* @param ignoreHashtagComment <code>true</code> si on doit ignorer les lignes commentés (commençant par un #)
|
||||||
|
* @param trimOutput <code>true</code> si on doit appeller la méthode String.trim() sur chaque ligne retournée
|
||||||
|
* @param f le fichier à lire
|
||||||
|
* @return la liste des lignes utiles
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
protected static List<String> getFileLines(boolean ignoreEmpty, boolean ignoreHashtagComment, boolean trimOutput, File f) throws IOException {
|
||||||
|
if (!f.isFile())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(f));
|
||||||
|
|
||||||
|
List<String> lines = new ArrayList<String>();
|
||||||
|
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
String trimmedLine = line.trim();
|
||||||
|
|
||||||
|
if (ignoreEmpty && trimmedLine.equals(""))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ignoreHashtagComment && trimmedLine.startsWith("#"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (trimOutput)
|
||||||
|
lines.add(trimmedLine);
|
||||||
|
else
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
7
src/fr/pandacube/java/util/Callback.java
Normal file
7
src/fr/pandacube/java/util/Callback.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Callback<T> {
|
||||||
|
public void done(T arg);
|
||||||
|
}
|
||||||
|
|
67
src/fr/pandacube/java/util/EnumUtil.java
Normal file
67
src/fr/pandacube/java/util/EnumUtil.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
public class EnumUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all enum constants which are in the specified enum class.
|
||||||
|
* @param enumType the enum class.
|
||||||
|
* @param separator a string which will be used as a separator
|
||||||
|
* @return a string representation of the enum class.
|
||||||
|
*/
|
||||||
|
public static <T extends Enum<T>> String enumList(Class<T> enumType, String separator) {
|
||||||
|
T[] elements = enumType.getEnumConstants();
|
||||||
|
|
||||||
|
String out = "";
|
||||||
|
boolean first = true;
|
||||||
|
for (T el : elements) {
|
||||||
|
if (!first) {
|
||||||
|
out += separator;
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
out += el.name();
|
||||||
|
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all enum constants which are in the specified enum class. It is equivalent to call
|
||||||
|
* {@link #enumList(Class, String)} with the second parameter <code>", "</code>
|
||||||
|
* @param enumType the enum class.
|
||||||
|
* @return a string representation of the enum class.
|
||||||
|
*/
|
||||||
|
public static <T extends Enum<T>> String enumList(Class<T> enumType) {
|
||||||
|
return enumList(enumType, ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permet de rechercher l'existance d'un élément dans un enum, de façon insensible à la casse
|
||||||
|
* @param enumType la classe correpondant à l'enum à lister
|
||||||
|
* @param search l'élément à rechercher, insensible à la casse
|
||||||
|
* @return l'élément de l'énumarétion, si elle a été trouvée, null sinon
|
||||||
|
*/
|
||||||
|
public static <T extends Enum<T>> T searchEnum(Class<T> enumType, String search) {
|
||||||
|
T[] elements = enumType.getEnumConstants();
|
||||||
|
|
||||||
|
for (T el : elements)
|
||||||
|
if (el.name().equalsIgnoreCase(search))
|
||||||
|
return el;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne une valeur aléatoire parmis les élément de l'Enum spécifié en paramètre.
|
||||||
|
* @param enumType l'enum dans lequel piocher la valeur
|
||||||
|
* @return une des valeurs de l'enum
|
||||||
|
*/
|
||||||
|
public static <T extends Enum<T>> T randomValue(Class<T> enumType) {
|
||||||
|
T[] elements = enumType.getEnumConstants();
|
||||||
|
|
||||||
|
return elements[RandomUtil.rand.nextInt(elements.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
772
src/fr/pandacube/java/util/JArithmeticInterpreter.java
Normal file
772
src/fr/pandacube/java/util/JArithmeticInterpreter.java
Normal file
@ -0,0 +1,772 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
//***
|
||||||
|
//*** INTERPRETEUR ARITHMETIQUE version 2.1 Version Java
|
||||||
|
//***
|
||||||
|
//***
|
||||||
|
//***
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
/*
|
||||||
|
Historique:
|
||||||
|
|
||||||
|
2.1:
|
||||||
|
- Version Java disponible:
|
||||||
|
# les operateurs mathematiques disponibles sont ceux de Java donc certains manquent.
|
||||||
|
|
||||||
|
2.0:
|
||||||
|
- Portage en C++ et debut en Java
|
||||||
|
|
||||||
|
Version C++:
|
||||||
|
|
||||||
|
- Meilleure gestion memoire lors de la construction de l'expression.
|
||||||
|
- Acceleration de certaines operations.
|
||||||
|
|
||||||
|
Version Java:
|
||||||
|
|
||||||
|
- Premiere version. Normalement ca doit marcher
|
||||||
|
|
||||||
|
1.3b: ajoute les fonctions suivantes: (NON DISTRIBUEE)
|
||||||
|
- reconnaissance du symbole <EFBFBD>
|
||||||
|
- ecriture formatee d'expression (<EFBFBD> ameliorer)
|
||||||
|
|
||||||
|
1.2: corrige les bugs suivants:
|
||||||
|
- erreur sur l'interpretation de fonctions unaires imbriquees telles que ln(exp(x)).
|
||||||
|
- la fonction puissance (pour les puissances entieres).
|
||||||
|
ajoute:
|
||||||
|
- la verification de la chaine entree (voir code d'erreur)
|
||||||
|
- la verification de l'existence de l'evaluation (voir code d'erreur)
|
||||||
|
|
||||||
|
|
||||||
|
1.1: corrige un bug au niveau de l'interpretation des fonctions du type:
|
||||||
|
|
||||||
|
exp(-(x+y))
|
||||||
|
|
||||||
|
1.0: premiere version
|
||||||
|
|
||||||
|
Le code source peut etre librement modifie et distribue.
|
||||||
|
|
||||||
|
Puisqu'il s'agit d'un essai en Java, le code ne doit pas etre super genial et merite sans doute
|
||||||
|
quelques modifications.En particulier, il serait interessant de rajouter le support des Exceptions
|
||||||
|
pour les calculs (division par zero, etc...).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Classe servant <EFBFBD> palier l'absence de passage par variables ou reference
|
||||||
|
|
||||||
|
class VariableInt {
|
||||||
|
public int mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Classe principale
|
||||||
|
|
||||||
|
public class JArithmeticInterpreter {
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
|
||||||
|
int mOperator;
|
||||||
|
double mValue;
|
||||||
|
JArithmeticInterpreter fg, fd;
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
|
||||||
|
//.................................................................................... Node
|
||||||
|
|
||||||
|
private JArithmeticInterpreter() {
|
||||||
|
this(0, 0, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//.................................................................................... Node
|
||||||
|
|
||||||
|
private JArithmeticInterpreter(int Operator,double Value,JArithmeticInterpreter Fg,JArithmeticInterpreter Fd) {
|
||||||
|
mOperator=Operator;
|
||||||
|
mValue=Value;
|
||||||
|
fg=Fg;
|
||||||
|
fd=Fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JArithmeticInterpreter(int Operator,double Value) {
|
||||||
|
this(Operator, Value, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//.................................................................................... Construct_Tree
|
||||||
|
|
||||||
|
private static JArithmeticInterpreter constructTree(StringBuffer string,int length,int error) {
|
||||||
|
int imbric,Bimbric;
|
||||||
|
int priorite,ope;
|
||||||
|
int position,positionv,i,j;
|
||||||
|
int opetemp=0;
|
||||||
|
int espa=0,espat=0;
|
||||||
|
int caspp=0;
|
||||||
|
|
||||||
|
JArithmeticInterpreter node;
|
||||||
|
|
||||||
|
// Initialisation des variables
|
||||||
|
|
||||||
|
if (length<=0) {
|
||||||
|
error=3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ope=0;
|
||||||
|
imbric=0;Bimbric=128;
|
||||||
|
priorite=6;
|
||||||
|
i=0;
|
||||||
|
positionv=position=0;
|
||||||
|
|
||||||
|
// Mise en place des donnees sur le morceau de chaine
|
||||||
|
|
||||||
|
while (i<length) {
|
||||||
|
|
||||||
|
if (((string.charAt(i)>47) && (string.charAt(i)<58)) || (string.charAt(i)=='<27>')) {
|
||||||
|
if (priorite>5) {
|
||||||
|
priorite=5;
|
||||||
|
positionv=i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((string.charAt(i)>96) && (string.charAt(i)<117)) {
|
||||||
|
VariableInt Vopetemp,Vespat;
|
||||||
|
|
||||||
|
Vopetemp= new VariableInt();
|
||||||
|
Vespat= new VariableInt();
|
||||||
|
|
||||||
|
Vopetemp.mValue=opetemp;
|
||||||
|
Vespat.mValue=espat;
|
||||||
|
|
||||||
|
FindOperator(Vopetemp,Vespat,string,i);
|
||||||
|
|
||||||
|
opetemp=Vopetemp.mValue;
|
||||||
|
espat=Vespat.mValue;
|
||||||
|
|
||||||
|
if (opetemp>=0) {
|
||||||
|
if (imbric<Bimbric) {
|
||||||
|
Bimbric=imbric;
|
||||||
|
ope=opetemp;
|
||||||
|
position=i;
|
||||||
|
priorite=4;
|
||||||
|
espa=espat;
|
||||||
|
}
|
||||||
|
else if ((imbric==Bimbric) && (priorite >=4)) {
|
||||||
|
ope=opetemp;
|
||||||
|
position=i;
|
||||||
|
priorite=4;
|
||||||
|
espa=espat;
|
||||||
|
}
|
||||||
|
j=i+1;
|
||||||
|
i+=espat;
|
||||||
|
while(j<i)
|
||||||
|
j++;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (string.charAt(i)=='t') {
|
||||||
|
if (priorite==6) ope=-1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (string.charAt(i)=='p') {
|
||||||
|
if (priorite==6) ope=-2;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (string.charAt(i)=='r') {
|
||||||
|
if (priorite==6) ope=-2;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (string.charAt(i)=='n') {
|
||||||
|
if (priorite==6) ope=-1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error=2; // symbole non reconnu
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch(string.charAt(i)) {
|
||||||
|
case '(':
|
||||||
|
imbric++;
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
imbric--;
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
if (imbric<Bimbric) {
|
||||||
|
Bimbric=imbric;
|
||||||
|
priorite=1;
|
||||||
|
ope=1;
|
||||||
|
position=i;
|
||||||
|
caspp=0;
|
||||||
|
}
|
||||||
|
else if ((imbric==Bimbric) && (priorite >=1)) {
|
||||||
|
priorite=1;
|
||||||
|
ope=1;
|
||||||
|
position=i;
|
||||||
|
caspp=0;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
if (imbric<Bimbric) {
|
||||||
|
if ((i-1)<0) {
|
||||||
|
if (priorite>5) {
|
||||||
|
priorite=1;
|
||||||
|
position=i;
|
||||||
|
ope=2;
|
||||||
|
Bimbric=imbric;
|
||||||
|
caspp=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.charAt(i-1)=='(') {
|
||||||
|
if (priorite>1){
|
||||||
|
priorite=1;
|
||||||
|
position=i;
|
||||||
|
Bimbric=imbric;
|
||||||
|
caspp=1;
|
||||||
|
ope=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Bimbric=imbric;
|
||||||
|
priorite=1;
|
||||||
|
ope=2;
|
||||||
|
position=i;
|
||||||
|
caspp=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((imbric==Bimbric) && (priorite>=1)) {
|
||||||
|
if ((i-1)<0) {
|
||||||
|
if (priorite>5) {
|
||||||
|
priorite=1;
|
||||||
|
position=i;
|
||||||
|
ope=2;
|
||||||
|
caspp=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (string.charAt(i-1)=='(') {
|
||||||
|
if (priorite>1){
|
||||||
|
priorite=1;
|
||||||
|
position=i;
|
||||||
|
caspp=1;
|
||||||
|
ope=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
priorite=1;
|
||||||
|
ope=2;
|
||||||
|
position=i;
|
||||||
|
caspp=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
if (imbric<Bimbric) {
|
||||||
|
Bimbric=imbric;
|
||||||
|
priorite=2;
|
||||||
|
ope=3;
|
||||||
|
position=i;
|
||||||
|
}
|
||||||
|
else if ((imbric==Bimbric) && (priorite>=2)) {
|
||||||
|
priorite=2;
|
||||||
|
ope=3;
|
||||||
|
position=i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
if (imbric<Bimbric) {
|
||||||
|
Bimbric=imbric;
|
||||||
|
priorite=2;
|
||||||
|
ope=4;
|
||||||
|
position=i;
|
||||||
|
}
|
||||||
|
else if ((imbric==Bimbric) && (priorite>=2)) {
|
||||||
|
priorite=2;
|
||||||
|
ope=4;
|
||||||
|
position=i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '^':
|
||||||
|
if (imbric<Bimbric) {
|
||||||
|
Bimbric=imbric;
|
||||||
|
priorite=3;
|
||||||
|
ope=5;
|
||||||
|
position=i;
|
||||||
|
}
|
||||||
|
else if ((imbric==Bimbric) && (priorite>=3)) {
|
||||||
|
priorite=3;
|
||||||
|
ope=5;
|
||||||
|
position=i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error=2; // symbole non reconnu
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imbric!=0) {
|
||||||
|
error=1; // erreur de "parenthesage"
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traitement des donnees
|
||||||
|
|
||||||
|
if (priorite==6) {
|
||||||
|
node =new JArithmeticInterpreter(ope,0.0);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
else if (caspp==1) {
|
||||||
|
node = new JArithmeticInterpreter(2,0);
|
||||||
|
|
||||||
|
node.fg= new JArithmeticInterpreter(0,0);
|
||||||
|
node.fd= new JArithmeticInterpreter();
|
||||||
|
|
||||||
|
if ((length-position-1-Bimbric)==0) { // argument absent
|
||||||
|
error=3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuffer temp=CopyPartialString(string,(position+1),(length-1-Bimbric));
|
||||||
|
node.fd=constructTree(temp,(length-position-1-Bimbric),error);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (priorite==5) {
|
||||||
|
node = new JArithmeticInterpreter(0,calc_const(string,positionv),null,null);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
else if (ope>5) {
|
||||||
|
node = new JArithmeticInterpreter(ope,0,null,null);
|
||||||
|
|
||||||
|
if ((length-position-espa-Bimbric)==0) { // argument absent
|
||||||
|
error=3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuffer temp=CopyPartialString(string,(position+espa),(length-1));
|
||||||
|
node.fg=constructTree(temp,(length-position-espa-Bimbric),error);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
node = new JArithmeticInterpreter(ope,0,null,null);
|
||||||
|
|
||||||
|
if ((position-Bimbric)==0) { // argument absent
|
||||||
|
error=3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuffer temp=CopyPartialString(string,Bimbric,(position-1));
|
||||||
|
node.fg=constructTree(temp,(position-Bimbric),error);
|
||||||
|
if ((length-position-1-Bimbric)==0) { // argument absent
|
||||||
|
error=3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
temp=CopyPartialString(string,(position+1),(length-1-Bimbric));
|
||||||
|
node.fd=constructTree(temp,(length-position-1-Bimbric),error);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//....................................................................................
|
||||||
|
|
||||||
|
private double computeTree() {
|
||||||
|
if (mOperator==0) return mValue;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
double valueL=fg.computeTree();
|
||||||
|
|
||||||
|
if (error!=0) return 0;
|
||||||
|
double valueR=0;
|
||||||
|
|
||||||
|
if (fd!=null) valueR=fd.computeTree();
|
||||||
|
if (error!=0) return 0;
|
||||||
|
|
||||||
|
switch(mOperator) {
|
||||||
|
case 1: // +
|
||||||
|
return (valueL+valueR);
|
||||||
|
case 2: // -
|
||||||
|
return (valueL-valueR);
|
||||||
|
case 3: // *
|
||||||
|
return (valueL*valueR);
|
||||||
|
case 4: // -
|
||||||
|
if (valueR==0) {
|
||||||
|
error=1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (valueL/valueR);
|
||||||
|
case 5: // ^
|
||||||
|
return Math.pow(valueL,valueR);
|
||||||
|
case 6: // exp
|
||||||
|
return Math.exp(valueL);
|
||||||
|
case 7: // ln
|
||||||
|
if (valueL<=0) {
|
||||||
|
if (valueL<0) error=2;
|
||||||
|
else error=1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (Math.log(valueL)/Math.log(2));
|
||||||
|
case 8: // log
|
||||||
|
if (valueL<=0) {
|
||||||
|
if (valueL<0) error=2;
|
||||||
|
else error=1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return Math.log(valueL);
|
||||||
|
case 9: // sqrt
|
||||||
|
if (valueL<0) {
|
||||||
|
error=2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return Math.sqrt(valueL);
|
||||||
|
case 10: // abs
|
||||||
|
return Math.abs(valueL);
|
||||||
|
case 11:
|
||||||
|
return Math.sin(valueL); // sin
|
||||||
|
case 12:
|
||||||
|
return Math.cos(valueL); // cos
|
||||||
|
case 13:
|
||||||
|
return Math.tan(valueL); // tan
|
||||||
|
case 14:
|
||||||
|
return Math.asin(valueL); // asin
|
||||||
|
case 15:
|
||||||
|
return Math.acos(valueL); // acos
|
||||||
|
case 16:
|
||||||
|
return Math.atan(valueL); // atan
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.................................................................................... Write_Tree
|
||||||
|
|
||||||
|
private void writeTree(StringBuffer string) {
|
||||||
|
boolean parenthese=false;
|
||||||
|
|
||||||
|
switch(mOperator) {
|
||||||
|
case 0:
|
||||||
|
string.append(StringUtil.formatDouble(mValue));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append('+');
|
||||||
|
fd.writeTree(string);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if ((fg.mOperator==0) && (fg.mValue==0));
|
||||||
|
else fg.writeTree(string);
|
||||||
|
string.append('-');
|
||||||
|
if ((fd.mOperator==1) || (fd.mOperator==2)) {
|
||||||
|
parenthese=true;
|
||||||
|
string.append('(');
|
||||||
|
}
|
||||||
|
fd.writeTree(string);
|
||||||
|
if (parenthese==true) {
|
||||||
|
string.append(')');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if ((fg.mOperator==1) || (fg.mOperator==2)) {
|
||||||
|
parenthese=true;
|
||||||
|
string.append('(');
|
||||||
|
}
|
||||||
|
fg.writeTree(string);
|
||||||
|
if (parenthese==true)
|
||||||
|
string.append(')');
|
||||||
|
parenthese=false;
|
||||||
|
string.append('*');
|
||||||
|
if ((fd.mOperator==1) || (fd.mOperator==2)) {
|
||||||
|
parenthese=true;
|
||||||
|
string.append('(');
|
||||||
|
}
|
||||||
|
fd.writeTree(string);
|
||||||
|
if (parenthese==true)
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if ((fg.mOperator==1) || (fg.mOperator==2)) {
|
||||||
|
parenthese=true;
|
||||||
|
string.append('(');
|
||||||
|
}
|
||||||
|
fg.writeTree(string);
|
||||||
|
if (parenthese==true)
|
||||||
|
string.append(')');
|
||||||
|
parenthese=false;
|
||||||
|
string.append('/');
|
||||||
|
if ((fd.mOperator>0) && (fd.mOperator<5)) {
|
||||||
|
parenthese=true;
|
||||||
|
string.append('(');
|
||||||
|
}
|
||||||
|
fd.writeTree(string);
|
||||||
|
if (parenthese==true)
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if ((fg.mOperator>0) && (fg.mOperator<5)) {
|
||||||
|
parenthese=true;
|
||||||
|
string.append('(');
|
||||||
|
}
|
||||||
|
fg.writeTree(string);
|
||||||
|
if (parenthese==true)
|
||||||
|
string.append(')');
|
||||||
|
parenthese=false;
|
||||||
|
string.append('^');
|
||||||
|
if ((fd.mOperator>0) && (fd.mOperator<5)) {
|
||||||
|
parenthese=true;
|
||||||
|
string.append('(');
|
||||||
|
}
|
||||||
|
fd.writeTree(string);
|
||||||
|
if (parenthese==true)
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
string.append("exp(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
string.append("log(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
string.append("ln(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
string.append("sqrt(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
string.append("|");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append('|');
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
string.append("sin(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
string.append("cos(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
string.append("tan(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
string.append("asin(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
string.append("acos(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
string.append("atan(");
|
||||||
|
fg.writeTree(string);
|
||||||
|
string.append(')');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.................................................................................... calc_const
|
||||||
|
|
||||||
|
private static double calc_const(StringBuffer chaine,int pos) {
|
||||||
|
int i=pos,j;
|
||||||
|
double temp=0;
|
||||||
|
int signe=1;
|
||||||
|
int longueur=chaine.length();
|
||||||
|
|
||||||
|
|
||||||
|
if (chaine.charAt(i)=='-') {
|
||||||
|
signe=-1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (chaine.charAt(i)=='π') return signe*Math.PI;
|
||||||
|
|
||||||
|
while (i<longueur && chaine.charAt(i)>47 && chaine.charAt(i)<58) {
|
||||||
|
temp=temp*10+(chaine.charAt(i)-48);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i<longueur && chaine.charAt(i)=='.') {
|
||||||
|
i++;
|
||||||
|
j=1;
|
||||||
|
while (i<longueur && chaine.charAt(i)>47 && chaine.charAt(i)<58) {
|
||||||
|
temp=temp+(chaine.charAt(i)-48)*Math.exp(-j*2.30258509);
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (signe*temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//.................................................................................... FindOperator
|
||||||
|
|
||||||
|
private static void FindOperator(VariableInt oper,VariableInt esp,StringBuffer chaine,int pos) {
|
||||||
|
switch(chaine.charAt(pos)) {
|
||||||
|
case 'a':
|
||||||
|
switch(chaine.charAt(pos+1)) {
|
||||||
|
case 'b':
|
||||||
|
esp.mValue=3;
|
||||||
|
oper.mValue=10;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
esp.mValue=4;
|
||||||
|
oper.mValue=15;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
esp.mValue=4;
|
||||||
|
oper.mValue=14;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
esp.mValue=4;
|
||||||
|
oper.mValue=16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (chaine.charAt(pos+1)=='h') {
|
||||||
|
esp.mValue=2;
|
||||||
|
oper.mValue=18;
|
||||||
|
}
|
||||||
|
else if ((chaine.charAt(pos+1)=='o') && (chaine.charAt(pos+2)=='s')) {
|
||||||
|
if (chaine.charAt(pos+3)=='h') {
|
||||||
|
esp.mValue=4;
|
||||||
|
oper.mValue=18;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
esp.mValue=3;
|
||||||
|
oper.mValue=12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
if ((chaine.charAt(pos+1)=='x') && (chaine.charAt(pos+2)=='p')) {
|
||||||
|
esp.mValue=3;
|
||||||
|
oper.mValue=6;
|
||||||
|
}
|
||||||
|
else oper.mValue=-10;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (chaine.charAt(pos+1)=='n') {
|
||||||
|
esp.mValue=2;
|
||||||
|
oper.mValue=7;
|
||||||
|
}
|
||||||
|
else if ((chaine.charAt(pos+1)=='o') && (chaine.charAt(pos+2)=='g')){
|
||||||
|
esp.mValue=3;
|
||||||
|
oper.mValue=8;
|
||||||
|
}
|
||||||
|
else oper.mValue=-10;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
if (chaine.charAt(pos+1)=='h') {
|
||||||
|
esp.mValue=2;
|
||||||
|
oper.mValue=17;
|
||||||
|
}
|
||||||
|
else if (chaine.charAt(pos+1)=='q') {
|
||||||
|
esp.mValue=4;
|
||||||
|
oper.mValue=9;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (chaine.charAt(pos+3)=='h') {
|
||||||
|
esp.mValue=4;
|
||||||
|
oper.mValue=17;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
esp.mValue=3;
|
||||||
|
oper.mValue=11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
if (chaine.charAt(pos+1)=='h') {
|
||||||
|
esp.mValue=2;
|
||||||
|
oper.mValue=19;
|
||||||
|
}
|
||||||
|
else if ((chaine.charAt(pos+1)=='a') && (chaine.charAt(pos+2)=='n')) {
|
||||||
|
if (chaine.charAt(pos+3)=='h') {
|
||||||
|
esp.mValue=4;
|
||||||
|
oper.mValue=19;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
esp.mValue=3;
|
||||||
|
oper.mValue=13;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else oper.mValue=-10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
oper.mValue=-10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//.................................................................................... CopyPartialString
|
||||||
|
|
||||||
|
private static StringBuffer CopyPartialString(StringBuffer chaine,int debut,int fin) {
|
||||||
|
StringBuffer chartemp;
|
||||||
|
int a=fin-debut+1;
|
||||||
|
chartemp=new StringBuffer(a+1);
|
||||||
|
|
||||||
|
for(int i=0;i<a;i++) chartemp.append(chaine.charAt(debut+i));
|
||||||
|
|
||||||
|
return chartemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static double getResultFromExpression(String expr, StringBuffer writeTree)
|
||||||
|
{
|
||||||
|
StringBuffer input = new StringBuffer(expr);
|
||||||
|
|
||||||
|
JArithmeticInterpreter jai = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
jai = JArithmeticInterpreter.constructTree(input,input.length(),0);
|
||||||
|
} catch (Exception e) { }
|
||||||
|
|
||||||
|
if (jai==null)
|
||||||
|
throw new IllegalArgumentException("Le calcul passé en paramètre est invalide");
|
||||||
|
|
||||||
|
if (writeTree != null)
|
||||||
|
{
|
||||||
|
writeTree.setLength(0);
|
||||||
|
jai.writeTree(writeTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jai.computeTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getResultFromExpression(String expr)
|
||||||
|
{
|
||||||
|
return getResultFromExpression(expr, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
|
||||||
|
StringBuffer b = new StringBuffer(0);
|
||||||
|
|
||||||
|
String disp_res = StringUtil.formatDouble(JArithmeticInterpreter.getResultFromExpression("1245.25*2", b));
|
||||||
|
|
||||||
|
System.out.println(disp_res);
|
||||||
|
System.out.println(b);
|
||||||
|
} // */
|
||||||
|
|
||||||
|
}
|
25
src/fr/pandacube/java/util/MemoryUtil.java
Normal file
25
src/fr/pandacube/java/util/MemoryUtil.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
public class MemoryUtil {
|
||||||
|
public static String humanReadableSize(long octet)
|
||||||
|
{
|
||||||
|
DecimalFormat format = new DecimalFormat("#####0.00");
|
||||||
|
double size = octet;
|
||||||
|
if (size < 1024)
|
||||||
|
return size+"o";
|
||||||
|
size /= 1024;
|
||||||
|
if (size < 1024)
|
||||||
|
return format.format(size)+"kio";
|
||||||
|
size /= 1024;
|
||||||
|
if (size < 1024)
|
||||||
|
return format.format(size)+"Mio";
|
||||||
|
size /= 1024;
|
||||||
|
if (size < 1024)
|
||||||
|
return format.format(size)+"Gio";
|
||||||
|
size /= 1024;
|
||||||
|
|
||||||
|
return format.format(size)+"Tio";
|
||||||
|
}
|
||||||
|
}
|
21
src/fr/pandacube/java/util/MinecraftVersion.java
Normal file
21
src/fr/pandacube/java/util/MinecraftVersion.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
public enum MinecraftVersion {
|
||||||
|
v1_7_2_to_1_7_5(4),
|
||||||
|
v1_7_6_to_1_7_10(5),
|
||||||
|
v1_8(47);
|
||||||
|
|
||||||
|
public final int versionNumber;
|
||||||
|
|
||||||
|
private MinecraftVersion(int v) {
|
||||||
|
versionNumber = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinecraftVersion getVersion(int v) {
|
||||||
|
for (MinecraftVersion mcV : MinecraftVersion.values())
|
||||||
|
if (mcV.versionNumber == v)
|
||||||
|
return mcV;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
52
src/fr/pandacube/java/util/PlayerFinder.java
Normal file
52
src/fr/pandacube/java/util/PlayerFinder.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import net.alpenblock.bungeeperms.BungeePerms;
|
||||||
|
|
||||||
|
public class PlayerFinder {
|
||||||
|
|
||||||
|
private static BungeePerms getPermPlugin() {
|
||||||
|
try {
|
||||||
|
return BungeePerms.getInstance();
|
||||||
|
} catch(NoClassDefFoundError|Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String getPlayerName(UUID id) {
|
||||||
|
BungeePerms pl = getPermPlugin();
|
||||||
|
if (pl == null) return null;
|
||||||
|
|
||||||
|
return pl.getPermissionsManager().getUUIDPlayerDB().getPlayerName(id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static UUID getPlayerId(String name) {
|
||||||
|
if (!isValidPlayerName(name)) return null; // évite une recherche inutile dans la base de donnée
|
||||||
|
BungeePerms pl = getPermPlugin();
|
||||||
|
if (pl == null) return null;
|
||||||
|
|
||||||
|
return pl.getPermissionsManager().getUUIDPlayerDB().getUUID(name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isValidPlayerName(String name) {
|
||||||
|
if (name == null) return false;
|
||||||
|
return name.matches("[0-9a-zA-Z_]{2,16}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
19
src/fr/pandacube/java/util/RandomUtil.java
Normal file
19
src/fr/pandacube/java/util/RandomUtil.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class RandomUtil {
|
||||||
|
|
||||||
|
public static Random rand = new Random();
|
||||||
|
|
||||||
|
|
||||||
|
public static int nextIntBetween(int minInclu, int maxExclu) {
|
||||||
|
return rand.nextInt(maxExclu-minInclu)+minInclu;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static double nextDoubleBetween(double minInclu, double maxExclu) {
|
||||||
|
return rand.nextDouble()*(maxExclu-minInclu)+minInclu;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
167
src/fr/pandacube/java/util/ServerPropertyFile.java
Normal file
167
src/fr/pandacube/java/util/ServerPropertyFile.java
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class ServerPropertyFile {
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
|
||||||
|
private Map<String, Object> data;
|
||||||
|
|
||||||
|
|
||||||
|
public ServerPropertyFile(File f) {
|
||||||
|
if (f == null) throw new IllegalArgumentException("f ne doit pas être null");
|
||||||
|
file = f;
|
||||||
|
|
||||||
|
data = new HashMap<String, Object>();
|
||||||
|
data.put("name", "default_name");
|
||||||
|
data.put("memory", "512M");
|
||||||
|
data.put("javaArgs", "");
|
||||||
|
data.put("MinecraftArgs", "");
|
||||||
|
data.put("jarFile", "");
|
||||||
|
data.put("isLobby", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Charge le fichier de configuration dans cette instance de la classe
|
||||||
|
* @return true si le chargement a réussi, false sinon
|
||||||
|
*/
|
||||||
|
public boolean loadFromFile() {
|
||||||
|
BufferedReader in = null;
|
||||||
|
try {
|
||||||
|
in = new BufferedReader(new FileReader(file));
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, Object> dataFile = new Gson().fromJson(in, Map.class);
|
||||||
|
|
||||||
|
if (!dataFile.containsKey("name") || !(dataFile.get("name") instanceof String))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!dataFile.containsKey("memory") || !(dataFile.get("memory") instanceof String))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!dataFile.containsKey("javaArgs") || !(dataFile.get("javaArgs") instanceof String))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!dataFile.containsKey("MinecraftArgs") || !(dataFile.get("MinecraftArgs") instanceof String))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!dataFile.containsKey("jarFile") || !(dataFile.get("jarFile") instanceof String))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!dataFile.containsKey("isLobby") || !(dataFile.get("isLobby") instanceof Boolean))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
data = dataFile;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (Exception e) { }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public boolean save() {
|
||||||
|
BufferedWriter out = null;
|
||||||
|
try {
|
||||||
|
out = new BufferedWriter(new FileWriter(file,false));
|
||||||
|
|
||||||
|
String jsonStr = new Gson().toJson(data);
|
||||||
|
|
||||||
|
out.append(jsonStr);
|
||||||
|
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (Exception e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return (String) data.get("name");
|
||||||
|
}
|
||||||
|
public String getMemory() {
|
||||||
|
return (String) data.get("memory");
|
||||||
|
}
|
||||||
|
public String getJavaArgs() {
|
||||||
|
return (String) data.get("javaArgs");
|
||||||
|
}
|
||||||
|
public String getMinecraftArgs() {
|
||||||
|
return (String) data.get("MinecraftArgs");
|
||||||
|
}
|
||||||
|
public String getJarFile() {
|
||||||
|
return (String) data.get("jarFile");
|
||||||
|
}
|
||||||
|
public boolean getIsLobby() {
|
||||||
|
return (boolean) data.get("isLobby");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setName(String n) {
|
||||||
|
if (n == null || !n.matches("^[a-zA-Z]$"))
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
data.put("name", n);
|
||||||
|
}
|
||||||
|
public void setMemory(String m) {
|
||||||
|
if (m == null || !m.matches("^[0-9]+[mgMG]$"))
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
data.put("memory", m);
|
||||||
|
}
|
||||||
|
public void setJavaArgs(String ja) {
|
||||||
|
if (ja == null)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
data.put("javaArgs", ja);
|
||||||
|
}
|
||||||
|
public void setMinecraftArgs(String ma) {
|
||||||
|
if (ma == null)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
data.put("MinecraftArgs", ma);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJarFile(String j) {
|
||||||
|
if (j == null)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
data.put("jarFile", j);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsLobby(boolean l) {
|
||||||
|
data.put("isLobby", l);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
26
src/fr/pandacube/java/util/StringUtil.java
Normal file
26
src/fr/pandacube/java/util/StringUtil.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
public class StringUtil {
|
||||||
|
public static String formatDouble(double d)
|
||||||
|
{
|
||||||
|
if(d == (long) d)
|
||||||
|
return String.format("%d",(long)d);
|
||||||
|
else
|
||||||
|
return String.valueOf(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param s Chaine de caractère à parcourir
|
||||||
|
* @param c_match le caractère dont on doit retourner le nombre d'occurence
|
||||||
|
* @return nombre d'occurence de <b>c_match</b> dans <b>s</b>
|
||||||
|
*/
|
||||||
|
public static int char_count(CharSequence s, char c_match)
|
||||||
|
{
|
||||||
|
char[] chars = s.toString().toCharArray();
|
||||||
|
int count = 0;
|
||||||
|
for (char c : chars)
|
||||||
|
if (c == c_match)
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
39
src/fr/pandacube/java/util/TimeUtil.java
Normal file
39
src/fr/pandacube/java/util/TimeUtil.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package fr.pandacube.java.util;
|
||||||
|
|
||||||
|
public class TimeUtil {
|
||||||
|
public static String durationToString (long msec_time, boolean dec_seconde)
|
||||||
|
{
|
||||||
|
int j = 0, h = 0, m = 0, s = 0;
|
||||||
|
long msec = msec_time;
|
||||||
|
|
||||||
|
j = (int) (msec / (1000 * 60 * 60 * 24));
|
||||||
|
msec -= (1000 * 60 * 60 * 24) * j;
|
||||||
|
h = (int) (msec / (1000 * 60 * 60));
|
||||||
|
msec -= (1000 * 60 * 60) * h;
|
||||||
|
m = (int) (msec / (1000 * 60));
|
||||||
|
msec -= (1000 * 60) * m;
|
||||||
|
s = (int) (msec / 1000);
|
||||||
|
msec -= 1000 * s;
|
||||||
|
|
||||||
|
String result = "";
|
||||||
|
if (j>0) result = result.concat(j+"j ");
|
||||||
|
if (h>0) result = result.concat(h+"h ");
|
||||||
|
if (m>0) result = result.concat(m+"m ");
|
||||||
|
if (s>0 && !dec_seconde) result = result.concat(s+"s");
|
||||||
|
else if (dec_seconde && (s>0 || msec > 0))
|
||||||
|
{
|
||||||
|
msec += s*1000;
|
||||||
|
result = result.concat((msec/1000D)+"s");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.equals(""))
|
||||||
|
result = "0";
|
||||||
|
|
||||||
|
return result.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String durationToString (long msec_time)
|
||||||
|
{
|
||||||
|
return durationToString(msec_time, false);
|
||||||
|
}
|
||||||
|
}
|
185
src/fr/pandacube/java/util/chat_display/Display.java
Normal file
185
src/fr/pandacube/java/util/chat_display/Display.java
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
package fr.pandacube.java.util.chat_display;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.HoverEvent;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
|
||||||
|
public class Display {
|
||||||
|
|
||||||
|
private BaseComponent first = new TextComponent("");
|
||||||
|
|
||||||
|
private BaseComponent current = null;
|
||||||
|
|
||||||
|
|
||||||
|
public Display() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour initialiser la composante suivante
|
||||||
|
*/
|
||||||
|
public Display(String legacyText) {
|
||||||
|
convertAndAddLegacy(legacyText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit un message en mettant à la ligne après chaque chaine passé en paramètre.<br/>
|
||||||
|
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour initialiser la composante suivante
|
||||||
|
*/
|
||||||
|
public Display(String[] legacyText) {
|
||||||
|
boolean f = true;
|
||||||
|
for (String s : legacyText) {
|
||||||
|
if (s == null) s = "";
|
||||||
|
if (!f)
|
||||||
|
first.addExtra("\n");
|
||||||
|
f = false;
|
||||||
|
convertAndAddLegacy(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Construit un message en mettant à la ligne après chaque chaine passé en paramètre.<br/>
|
||||||
|
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour initialiser la composante suivante
|
||||||
|
*/
|
||||||
|
public Display(List<String> legacyText) {
|
||||||
|
this(legacyText.toArray(new String[legacyText.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour initialiser la composante suivante
|
||||||
|
*/
|
||||||
|
public Display(BaseComponent firstComponent) {
|
||||||
|
if (firstComponent == null) throw new IllegalArgumentException("le paramètre ne doit pas être null");
|
||||||
|
first.addExtra(firstComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Après l'appel de cette méthode, vous devez appeler nextComponent() pour initialiser la composante suivante
|
||||||
|
*/
|
||||||
|
public Display convertAndAddLegacy(String legacyText) {
|
||||||
|
finalizeCurrentComponent();
|
||||||
|
|
||||||
|
if (legacyText == null)
|
||||||
|
return this;
|
||||||
|
BaseComponent[] compo = TextComponent.fromLegacyText(legacyText);
|
||||||
|
|
||||||
|
for (BaseComponent c : compo) {
|
||||||
|
first.addExtra(c);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Display nextComponent(String str) {
|
||||||
|
finalizeCurrentComponent();
|
||||||
|
if (str == null) str = "";
|
||||||
|
current = new TextComponent(str);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Display addComponent(BaseComponent cmp) {
|
||||||
|
if (cmp == null) throw new IllegalArgumentException("le paramètre ne doit pas être null");
|
||||||
|
finalizeCurrentComponent();
|
||||||
|
first.addExtra(cmp);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Équivalent à <code>nextComponent("\n")</code>, sauf qu'un nouvel appel à nextComponent() est nécessaire après.
|
||||||
|
*/
|
||||||
|
public Display nextLine() {
|
||||||
|
finalizeCurrentComponent();
|
||||||
|
first.addExtra(new TextComponent("\n"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setColor(ChatColor color) {
|
||||||
|
current.setColor(color);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setBold(boolean b) {
|
||||||
|
current.setBold(b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setItalic(boolean i) {
|
||||||
|
current.setItalic(i);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setUnderlined(boolean u) {
|
||||||
|
current.setUnderlined(u);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setObfuscated(boolean o) {
|
||||||
|
current.setObfuscated(o);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setStrikethrough(boolean s) {
|
||||||
|
current.setStrikethrough(s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setHoverText(Display content) {
|
||||||
|
current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] {content.get()}));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setClickURL(String url) {
|
||||||
|
current.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setClickCommand(String cmd) {
|
||||||
|
current.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, cmd));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Display setClickSuggest(String cmd) {
|
||||||
|
current.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, cmd));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void finalizeCurrentComponent() {
|
||||||
|
if (current != null)
|
||||||
|
first.addExtra(current);
|
||||||
|
current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public BaseComponent get() {
|
||||||
|
finalizeCurrentComponent();
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
223
src/fr/pandacube/java/util/chat_display/DisplayUtil.java
Normal file
223
src/fr/pandacube/java/util/chat_display/DisplayUtil.java
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
package fr.pandacube.java.util.chat_display;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
|
||||||
|
public class DisplayUtil {
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private static Map<Integer, String> charList = new HashMap<Integer, String>(){{
|
||||||
|
put(-6, "§");
|
||||||
|
put(2, "!.,:;i|¡");
|
||||||
|
put(3, "'`lìí");
|
||||||
|
put(4, " I[]tï×");
|
||||||
|
put(5, "\"()*<>fk{}");
|
||||||
|
put(7, "@~®");
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
private static final int defaultChatMaxWidth = 320;
|
||||||
|
private static int chatMaxWidth = defaultChatMaxWidth;
|
||||||
|
|
||||||
|
private static final int defaultNbCharPerLineForConsole = 50;
|
||||||
|
private static int nbCharPerLineForConsole = defaultNbCharPerLineForConsole;
|
||||||
|
|
||||||
|
public static final ChatColor COLOR_TITLE = ChatColor.GOLD;
|
||||||
|
public static final ChatColor COLOR_LINK = ChatColor.GREEN;
|
||||||
|
public static final ChatColor COLOR_COMMAND = ChatColor.GRAY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static BaseComponent createURLLink(String textLink, String url, String hoverText) {
|
||||||
|
String dispURL = (url.length() > 50) ? (url.substring(0, 48)+"...") : url;
|
||||||
|
|
||||||
|
return new Display()
|
||||||
|
.nextComponent(textLink)
|
||||||
|
.setClickURL(url)
|
||||||
|
.setHoverText(new Display(ChatColor.GRAY+((hoverText == null)?"Cliquez pour accéder au site :":hoverText)+"\n"+ChatColor.GRAY+dispURL))
|
||||||
|
.setColor(COLOR_LINK)
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static BaseComponent createCommandLink(String textLink, String commandWithSlash, String hoverText) {
|
||||||
|
Display d = new Display()
|
||||||
|
.nextComponent(textLink)
|
||||||
|
.setClickCommand(commandWithSlash)
|
||||||
|
.setColor(COLOR_COMMAND);
|
||||||
|
if (hoverText != null)
|
||||||
|
d.setHoverText(new Display(hoverText));
|
||||||
|
return d.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static BaseComponent createCommandSuggest(String textLink, String commandWithSlash, String hoverText) {
|
||||||
|
Display d = new Display()
|
||||||
|
.nextComponent(textLink)
|
||||||
|
.setClickSuggest(commandWithSlash)
|
||||||
|
.setColor(COLOR_COMMAND);
|
||||||
|
if (hoverText != null)
|
||||||
|
d.setHoverText(new Display(hoverText));
|
||||||
|
return d.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static BaseComponent centerText(BaseComponent text, char repeatedChar, ChatColor decorationColor, boolean console) {
|
||||||
|
|
||||||
|
int textWidth = strWidth(text.toPlainText(), console);
|
||||||
|
if (textWidth > ((console)?nbCharPerLineForConsole:chatMaxWidth)) return text;
|
||||||
|
|
||||||
|
|
||||||
|
String current = text.toPlainText();
|
||||||
|
int count = 0;
|
||||||
|
do {
|
||||||
|
count++;
|
||||||
|
current = repeatedChar + current + repeatedChar;
|
||||||
|
} while (strWidth(current, console) <= ((console)?nbCharPerLineForConsole:chatMaxWidth));
|
||||||
|
count--;
|
||||||
|
|
||||||
|
String finalLeftOrRight = "";
|
||||||
|
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
finalLeftOrRight += repeatedChar;
|
||||||
|
|
||||||
|
Display d = new Display().nextComponent(finalLeftOrRight).setColor(decorationColor)
|
||||||
|
.addComponent(text);
|
||||||
|
|
||||||
|
if (repeatedChar != ' ') {
|
||||||
|
d.nextComponent(finalLeftOrRight).setColor(decorationColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return d.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static BaseComponent leftText(BaseComponent text, char repeatedChar, ChatColor decorationColor, int nbLeft, boolean console) {
|
||||||
|
|
||||||
|
int textWidth = strWidth(text.toPlainText(), console);
|
||||||
|
if (textWidth > ((console)?nbCharPerLineForConsole:chatMaxWidth) || textWidth + nbLeft*charW(repeatedChar, console) > ((console)?nbCharPerLineForConsole:chatMaxWidth)) return text;
|
||||||
|
|
||||||
|
Display d = new Display();
|
||||||
|
|
||||||
|
String finalLeft = "";
|
||||||
|
if (nbLeft > 0) {
|
||||||
|
for (int i=0; i<nbLeft; i++)
|
||||||
|
finalLeft += repeatedChar;
|
||||||
|
d.nextComponent(finalLeft).setColor(decorationColor);
|
||||||
|
}
|
||||||
|
d.addComponent(text);
|
||||||
|
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
String current = finalLeft+text.toPlainText();
|
||||||
|
do {
|
||||||
|
count++;
|
||||||
|
current += repeatedChar;
|
||||||
|
} while (strWidth(current, console) <= ((console)?nbCharPerLineForConsole:chatMaxWidth));
|
||||||
|
count--;
|
||||||
|
|
||||||
|
|
||||||
|
if (repeatedChar != ' ') {
|
||||||
|
String finalRight = "";
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
finalRight += repeatedChar;
|
||||||
|
d.nextComponent(finalRight).setColor(decorationColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
public static BaseComponent rightText(BaseComponent text, char repeatedChar, ChatColor decorationColor, int nbRight, boolean console) {
|
||||||
|
|
||||||
|
int textWidth = strWidth(text.toPlainText(), console);
|
||||||
|
if (textWidth > ((console)?nbCharPerLineForConsole:chatMaxWidth) || textWidth + nbRight*charW(repeatedChar, console) > ((console)?nbCharPerLineForConsole:chatMaxWidth)) return text;
|
||||||
|
|
||||||
|
|
||||||
|
String tempText = text.toPlainText();
|
||||||
|
if (nbRight > 0) {
|
||||||
|
tempText += decorationColor;
|
||||||
|
for (int i=0; i<nbRight; i++)
|
||||||
|
tempText += repeatedChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
String current = tempText;
|
||||||
|
do {
|
||||||
|
count++;
|
||||||
|
current = repeatedChar + current;
|
||||||
|
} while (strWidth(current, console) <= ((console)?nbCharPerLineForConsole:chatMaxWidth));
|
||||||
|
count--;
|
||||||
|
|
||||||
|
String finalLeft = "";
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
finalLeft += repeatedChar;
|
||||||
|
|
||||||
|
Display d = new Display().nextComponent(finalLeft).setColor(decorationColor)
|
||||||
|
.addComponent(text);
|
||||||
|
|
||||||
|
|
||||||
|
if (repeatedChar != ' ') {
|
||||||
|
String finalRight = "";
|
||||||
|
for (int i=0; i<nbRight; i++)
|
||||||
|
finalRight += repeatedChar;
|
||||||
|
d.nextComponent(finalRight).setColor(decorationColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseComponent emptyLine(char repeatedChar, ChatColor decorationColor, boolean console) {
|
||||||
|
int count = ((console)?nbCharPerLineForConsole:chatMaxWidth)/charW(repeatedChar, console);
|
||||||
|
String finalLine = "";
|
||||||
|
for (int i=0;i<count;i++)
|
||||||
|
finalLine += repeatedChar;
|
||||||
|
|
||||||
|
return new Display().nextComponent(finalLine).setColor(decorationColor).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static int strWidth(String str, boolean console) {
|
||||||
|
int count = 0;
|
||||||
|
for (char c : str.toCharArray())
|
||||||
|
count += charW(c, console);
|
||||||
|
return (count < 0) ? 0 : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static int charW(char c, boolean console) {
|
||||||
|
if (console) return (c == '§') ? -1 : 1;
|
||||||
|
for (int px: charList.keySet())
|
||||||
|
if (charList.get(px).indexOf(c) >= 0)
|
||||||
|
return px;
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void setNbCharPerLineForConsole(int nb) {
|
||||||
|
if (nb < 0) nb = 0;
|
||||||
|
nbCharPerLineForConsole = nb;
|
||||||
|
}
|
||||||
|
public static void resetNbCharPerLineForConsole() {
|
||||||
|
nbCharPerLineForConsole = defaultNbCharPerLineForConsole;
|
||||||
|
}
|
||||||
|
public static void setChatMaxWidth(int px) {
|
||||||
|
if (px < 0) px = 0;
|
||||||
|
chatMaxWidth = px;
|
||||||
|
}
|
||||||
|
public static void resetChatMaxWidth() {
|
||||||
|
chatMaxWidth = defaultChatMaxWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
72
src/fr/pandacube/java/util/chat_display/TextProgressBar.java
Normal file
72
src/fr/pandacube/java/util/chat_display/TextProgressBar.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package fr.pandacube.java.util.chat_display;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
|
||||||
|
public class TextProgressBar {
|
||||||
|
private static String pattern_start = "[";
|
||||||
|
private static String pattern_end = "]";
|
||||||
|
private static ChatColor color_empty = ChatColor.DARK_GRAY;
|
||||||
|
private static ChatColor color_decoration = ChatColor.GOLD;
|
||||||
|
private static ChatColor color_default = ChatColor.RESET;
|
||||||
|
private static String pattern_empty = ".";
|
||||||
|
private static String pattern_full = "|";
|
||||||
|
|
||||||
|
public static String progressBar(double[] values, ChatColor[] colors, double total, int nbCar)
|
||||||
|
{
|
||||||
|
long[] sizes = new long[values.length];
|
||||||
|
|
||||||
|
int max_size = nbCar - pattern_start.length() - pattern_end.length();
|
||||||
|
|
||||||
|
for (int i=0; i<values.length; i++)
|
||||||
|
{
|
||||||
|
double sum_values_before = 0;
|
||||||
|
for (int j = i ; j>=0; j--)
|
||||||
|
sum_values_before += values[j];
|
||||||
|
|
||||||
|
long car_position = Math.round(max_size * sum_values_before / total);
|
||||||
|
|
||||||
|
// évite les barre de progressions plus grandes que la taille demandée
|
||||||
|
if (car_position > max_size) car_position = max_size;
|
||||||
|
|
||||||
|
long sum_sizes_before = 0;
|
||||||
|
for (int j = i-1 ; j>=0; j--)
|
||||||
|
sum_sizes_before += sizes[j];
|
||||||
|
|
||||||
|
sizes[i] = car_position - sum_sizes_before;
|
||||||
|
}
|
||||||
|
int sum_sizes = 0;
|
||||||
|
|
||||||
|
|
||||||
|
String bar = color_decoration+pattern_start;
|
||||||
|
for (int i=0; i<sizes.length; i++)
|
||||||
|
{
|
||||||
|
sum_sizes += sizes[i];
|
||||||
|
|
||||||
|
ChatColor color = color_default;
|
||||||
|
if (colors != null && i < colors.length && colors[i] != null)
|
||||||
|
color = colors[i];
|
||||||
|
|
||||||
|
bar = bar + color;
|
||||||
|
|
||||||
|
for (int j=0; j<sizes[i]; j++)
|
||||||
|
bar = bar + pattern_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
bar = bar + color_empty;
|
||||||
|
for (int j=0; j<(max_size-sum_sizes); j++)
|
||||||
|
bar = bar + pattern_empty;
|
||||||
|
|
||||||
|
bar = bar + color_decoration + pattern_end;
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String progressBar(double value, ChatColor color, double max, int nbCar)
|
||||||
|
{
|
||||||
|
double[] d = new double[1]; d[0] = value;
|
||||||
|
ChatColor[] c = new ChatColor[1]; c[0] = color;
|
||||||
|
return progressBar(d, c, max, nbCar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
57
src/fr/pandacube/java/util/db/DBConnection.java
Normal file
57
src/fr/pandacube/java/util/db/DBConnection.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class DBConnection {
|
||||||
|
JavaPlugin plugin;
|
||||||
|
Connection conn;
|
||||||
|
String url;
|
||||||
|
String login;
|
||||||
|
String pass;
|
||||||
|
|
||||||
|
public DBConnection(String host, int port, String dbname, String l, String p) throws ClassNotFoundException, SQLException {
|
||||||
|
Class.forName("com.mysql.jdbc.Driver");
|
||||||
|
url = "jdbc:mysql://"+host+":"+port+"/"+dbname;
|
||||||
|
login = l;
|
||||||
|
pass = p;
|
||||||
|
conn = DriverManager.getConnection(url, login, pass);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void reconnectIfNecessary() throws SQLException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
catch(SQLException e)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
conn = DriverManager.getConnection(url, login, pass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getConnection() throws SQLException
|
||||||
|
{
|
||||||
|
if (!conn.isValid(1))
|
||||||
|
reconnectIfNecessary();
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
conn.close();
|
||||||
|
} catch (Exception e) { }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
114
src/fr/pandacube/java/util/db/LoginHistoryElement.java
Normal file
114
src/fr/pandacube/java/util/db/LoginHistoryElement.java
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class LoginHistoryElement extends SQLElement {
|
||||||
|
|
||||||
|
|
||||||
|
private long time;
|
||||||
|
private String playerId;
|
||||||
|
private String ip;
|
||||||
|
private ActionType actionType;
|
||||||
|
private int nbOnline;
|
||||||
|
|
||||||
|
|
||||||
|
public LoginHistoryElement(long t, UUID pId, InetAddress IP, ActionType action, int nbO) {
|
||||||
|
super("pandacube_login_history");
|
||||||
|
setTime(t);
|
||||||
|
setPlayerId(pId);
|
||||||
|
setIp(IP);
|
||||||
|
setActionType(action);
|
||||||
|
setNbOnline(nbO);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginHistoryElement(int id, long t, String pId, String IP, ActionType action, int nbO) {
|
||||||
|
super("pandacube_login_history", id);
|
||||||
|
if (IP == null || pId == null)
|
||||||
|
throw new IllegalArgumentException("pId et IP ne peuvent être null");
|
||||||
|
setTime(t);
|
||||||
|
playerId = pId;
|
||||||
|
ip = IP;
|
||||||
|
setActionType(action);
|
||||||
|
setNbOnline(nbO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
Long.toString(time),
|
||||||
|
playerId,
|
||||||
|
ip,
|
||||||
|
actionType.toString(),
|
||||||
|
Integer.toString(nbOnline)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"time",
|
||||||
|
"playerId",
|
||||||
|
"ip",
|
||||||
|
"actionType",
|
||||||
|
"nbOnline"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(long time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UUID getPlayerId() {
|
||||||
|
return UUID.fromString(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerId(UUID pId) {
|
||||||
|
if (pId == null)
|
||||||
|
throw new IllegalArgumentException("pId ne peut être null");
|
||||||
|
playerId = pId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getIp() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIp(InetAddress addr) {
|
||||||
|
if (addr == null)
|
||||||
|
throw new IllegalArgumentException("addr ne peut être null");
|
||||||
|
ip = addr.getHostAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ActionType getActionType() {
|
||||||
|
return actionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActionType(ActionType actionT) {
|
||||||
|
if (actionT == null)
|
||||||
|
throw new IllegalArgumentException("actionT ne peut être null");
|
||||||
|
actionType = actionT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getNbOnline() {
|
||||||
|
return nbOnline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNbOnline(int nbOnline) {
|
||||||
|
this.nbOnline = nbOnline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum ActionType {
|
||||||
|
LOGIN, LOGOUT
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
src/fr/pandacube/java/util/db/LoginHistoryTable.java
Normal file
36
src/fr/pandacube/java/util/db/LoginHistoryTable.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import fr.pandacube.java.util.db.LoginHistoryElement.ActionType;
|
||||||
|
|
||||||
|
public class LoginHistoryTable extends SQLTable<LoginHistoryElement> {
|
||||||
|
|
||||||
|
public LoginHistoryTable() throws SQLException {
|
||||||
|
super("pandacube_login_history");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "time BIGINT NOT NULL,"
|
||||||
|
+ "playerId CHAR(36) NOT NULL,"
|
||||||
|
+ "ip VARCHAR(128) NOT NULL,"
|
||||||
|
+ "actionType ENUM('LOGIN', 'LOGOUT') NOT NULL,"
|
||||||
|
+ "nbOnline INT NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LoginHistoryElement getElementInstance(ResultSet sqlResult) throws SQLException {
|
||||||
|
LoginHistoryElement el = new LoginHistoryElement(
|
||||||
|
sqlResult.getInt("id"),
|
||||||
|
sqlResult.getLong("time"),
|
||||||
|
sqlResult.getString("playerId"),
|
||||||
|
sqlResult.getString("ip"),
|
||||||
|
ActionType.valueOf(sqlResult.getString("actionType")),
|
||||||
|
sqlResult.getInt("nbOnline"));
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
src/fr/pandacube/java/util/db/MPGroupElement.java
Normal file
63
src/fr/pandacube/java/util/db/MPGroupElement.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import fr.pandacube.java.util.PlayerFinder;
|
||||||
|
|
||||||
|
public class MPGroupElement extends SQLElement {
|
||||||
|
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public MPGroupElement(String name) {
|
||||||
|
super("pandacube_mp_group");
|
||||||
|
setGroupName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MPGroupElement(int id, String name) {
|
||||||
|
super("pandacube_mp_group", id);
|
||||||
|
setGroupName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
groupName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"groupName"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getGroupName() { return groupName; }
|
||||||
|
|
||||||
|
public void setGroupName(String name) {
|
||||||
|
if (name == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
if (!PlayerFinder.isValidPlayerName(name))
|
||||||
|
throw new IllegalArgumentException("Le nom d'un groupe doit respecter le pattern d'un pseudo valide");
|
||||||
|
groupName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<MPGroupUserElement> getUsers() throws SQLException {
|
||||||
|
return ORM.getTable(MPGroupUserTable.class)
|
||||||
|
.getAll("groupId = "+getId(), "id ASC", null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
26
src/fr/pandacube/java/util/db/MPGroupTable.java
Normal file
26
src/fr/pandacube/java/util/db/MPGroupTable.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class MPGroupTable extends SQLTable<MPGroupElement> {
|
||||||
|
|
||||||
|
public MPGroupTable() throws SQLException {
|
||||||
|
super("pandacube_mp_group");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "groupName VARCHAR(16) NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MPGroupElement getElementInstance(ResultSet sqlResult)
|
||||||
|
throws SQLException {
|
||||||
|
return new MPGroupElement(
|
||||||
|
sqlResult.getInt("id"),
|
||||||
|
sqlResult.getString("groupName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
71
src/fr/pandacube/java/util/db/MPGroupUserElement.java
Normal file
71
src/fr/pandacube/java/util/db/MPGroupUserElement.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MPGroupUserElement extends SQLElement {
|
||||||
|
|
||||||
|
private int groupId;
|
||||||
|
private String playerId;
|
||||||
|
|
||||||
|
|
||||||
|
public MPGroupUserElement(int gId, UUID pId) {
|
||||||
|
super("pandacube_mp_group_user");
|
||||||
|
setGroupId(gId);
|
||||||
|
setPlayerId(pId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MPGroupUserElement(int id, int gId, String pId) {
|
||||||
|
super("pandacube_mp_group_user", id);
|
||||||
|
setGroupId(gId);
|
||||||
|
setPlayerId(UUID.fromString(pId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
Integer.toString(groupId),
|
||||||
|
playerId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"groupId",
|
||||||
|
"playerId"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int getGroupId() { return groupId; }
|
||||||
|
public UUID getPlayerId() { return UUID.fromString(playerId); }
|
||||||
|
|
||||||
|
public void setGroupId(int gId) { groupId = gId; }
|
||||||
|
public void setPlayerId(UUID pId) {
|
||||||
|
if (pId == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
this.playerId = pId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public PlayerElement getPlayerElement() throws SQLException {
|
||||||
|
return ORM.getTable(PlayerTable.class)
|
||||||
|
.getFirst("playerId LIKE '"+getPlayerId()+"'", "id ASC");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
42
src/fr/pandacube/java/util/db/MPGroupUserTable.java
Normal file
42
src/fr/pandacube/java/util/db/MPGroupUserTable.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MPGroupUserTable extends SQLTable<MPGroupUserElement> {
|
||||||
|
|
||||||
|
public MPGroupUserTable() throws SQLException {
|
||||||
|
super("pandacube_mp_group_user");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "groupId INT NOT NULL,"
|
||||||
|
+ "playerId VARCHAR(36) NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MPGroupUserElement getElementInstance(ResultSet sqlResult)
|
||||||
|
throws SQLException {
|
||||||
|
return new MPGroupUserElement(
|
||||||
|
sqlResult.getInt("id"),
|
||||||
|
sqlResult.getInt("groupId"),
|
||||||
|
sqlResult.getString("playerId"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne l'instance de MPGroupUserElement correcpondant à la présence d'un joueur dans un groupe
|
||||||
|
* @param group le groupe concerné, sous forme d'instance de MPGroupElement
|
||||||
|
* @param player l'identifiant du joueur
|
||||||
|
* @return null si la correspondance n'a pas été trouvée
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
public MPGroupUserElement getPlayerInGroup(MPGroupElement group, UUID player) throws SQLException {
|
||||||
|
if (player == null || group == null) return null;
|
||||||
|
return getFirst("groupId = "+group.getId()+" AND playerId = '"+player+"'", "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
177
src/fr/pandacube/java/util/db/MPMessageElement.java
Normal file
177
src/fr/pandacube/java/util/db/MPMessageElement.java
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Représente un message dans la base de donnée<br/>
|
||||||
|
* <br/>
|
||||||
|
* Les propriétés suivantes doivent être complétés hors constructeur (par défaut <code>null</code>) :
|
||||||
|
* <ul>
|
||||||
|
* <li><code>destNick</code></li>
|
||||||
|
* <li>ou <code>destGroup</code></li>
|
||||||
|
* </ul>
|
||||||
|
* La propriété <code>deleted</code> est défini par défaut à Faux.
|
||||||
|
* @author Marc Baloup
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MPMessageElement extends SQLElement {
|
||||||
|
|
||||||
|
private long time;
|
||||||
|
private int securityKey; // permet de différencier deux message, dans le cas où 2 messages ont exactement la même valeur time
|
||||||
|
private String viewerId;
|
||||||
|
private String sourceId;
|
||||||
|
private String destId = null;
|
||||||
|
private Integer destGroup = null;
|
||||||
|
private String message;
|
||||||
|
private boolean wasRead;
|
||||||
|
private boolean deleted = false;
|
||||||
|
private boolean serverSync;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public MPMessageElement(long t, int secKey, UUID viewId, UUID srcId, String msg, boolean r, boolean sync) {
|
||||||
|
super("pandacube_mp_message");
|
||||||
|
setTime(t);
|
||||||
|
setSecurityKey(secKey);
|
||||||
|
setViewerId(viewId);
|
||||||
|
setSourceId(srcId);
|
||||||
|
setMessage(msg);
|
||||||
|
setRead(r);
|
||||||
|
setServerSync(sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected MPMessageElement(int id, long t, int secKey, String viewNick, String srcNick, String msg, boolean r, boolean sync) {
|
||||||
|
super("pandacube_mp_message", id);
|
||||||
|
setTime(t);
|
||||||
|
setSecurityKey(secKey);
|
||||||
|
setViewerId(UUID.fromString(viewNick));
|
||||||
|
setSourceId((srcNick == null) ? null : UUID.fromString(srcNick));
|
||||||
|
setMessage(msg);
|
||||||
|
setRead(r);
|
||||||
|
setServerSync(sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
Long.toString(time),
|
||||||
|
Integer.toString(securityKey),
|
||||||
|
viewerId,
|
||||||
|
sourceId,
|
||||||
|
destId,
|
||||||
|
(destGroup==null)?null:destGroup.toString(),
|
||||||
|
message,
|
||||||
|
(wasRead)?"1":"0",
|
||||||
|
(deleted)?"1":"0",
|
||||||
|
(serverSync)?"1":"0"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"time",
|
||||||
|
"securityKey",
|
||||||
|
"viewerId",
|
||||||
|
"sourceId",
|
||||||
|
"destId",
|
||||||
|
"destGroup",
|
||||||
|
"message",
|
||||||
|
"wasRead",
|
||||||
|
"deleted",
|
||||||
|
"serverSync"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long getTime() { return time; }
|
||||||
|
public int getSecurityKey() { return securityKey; }
|
||||||
|
public UUID getViewerId() { return UUID.fromString(viewerId); }
|
||||||
|
public UUID getSourceId() {
|
||||||
|
if (sourceId == null) return null;
|
||||||
|
return UUID.fromString(sourceId);
|
||||||
|
}
|
||||||
|
public UUID getDestId() {
|
||||||
|
if (destId == null) return null;
|
||||||
|
return UUID.fromString(destId);
|
||||||
|
}
|
||||||
|
public Integer getDestGroup() { return destGroup; }
|
||||||
|
public String getMessage() { return message; }
|
||||||
|
public boolean isRead() { return wasRead; }
|
||||||
|
public boolean isDeleted() { return deleted; }
|
||||||
|
public boolean isServerSync() { return serverSync; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setTime(long t) { time = t; }
|
||||||
|
public void setSecurityKey(int secKey) { securityKey = secKey; }
|
||||||
|
|
||||||
|
public void setViewerId(UUID viewId) {
|
||||||
|
if (viewId == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
viewerId = viewId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceId(UUID srcId) {
|
||||||
|
if (srcId == null) sourceId = null;
|
||||||
|
else sourceId = srcId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDestId(UUID destId) {
|
||||||
|
if (destId == null) this.destId = null;
|
||||||
|
else {
|
||||||
|
this.destId = destId.toString();
|
||||||
|
destGroup = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDestGroup(Integer destGroup) {
|
||||||
|
this.destGroup = destGroup;
|
||||||
|
if (destGroup != null)
|
||||||
|
destId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String msg) {
|
||||||
|
if (msg == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
message = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRead(boolean r) { wasRead = r; }
|
||||||
|
public void setDeleted(boolean del) { deleted = del; }
|
||||||
|
public void setServerSync(boolean sync) { serverSync = sync; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public MPGroupElement getDestGroupElement() throws SQLException {
|
||||||
|
if (getDestGroup() == null) return null;
|
||||||
|
|
||||||
|
return ORM.getTable(MPGroupTable.class).get(getDestGroup());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
99
src/fr/pandacube/java/util/db/MPMessageTable.java
Normal file
99
src/fr/pandacube/java/util/db/MPMessageTable.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import fr.pandacube.java.util.PlayerFinder;
|
||||||
|
|
||||||
|
public class MPMessageTable extends SQLTable<MPMessageElement> {
|
||||||
|
|
||||||
|
public MPMessageTable() throws SQLException {
|
||||||
|
super("pandacube_mp_message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "time BIGINT NOT NULL,"
|
||||||
|
+ "securityKey INT NOT NULL,"
|
||||||
|
+ "viewerId VARCHAR(36) NOT NULL,"
|
||||||
|
+ "sourceId VARCHAR(36) NULL," // Null si la source est la console ou une autre entité qu'un joueur
|
||||||
|
+ "destId VARCHAR(36) NULL,"
|
||||||
|
+ "destGroup INT NULL,"
|
||||||
|
+ "message VARCHAR(512) NOT NULL,"
|
||||||
|
+ "wasRead TINYINT NOT NULL,"
|
||||||
|
+ "deleted TINYINT NOT NULL,"
|
||||||
|
+ "serverSync TINYINT NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MPMessageElement getElementInstance(ResultSet sqlResult)
|
||||||
|
throws SQLException {
|
||||||
|
MPMessageElement el = new MPMessageElement(
|
||||||
|
sqlResult.getInt("id"),
|
||||||
|
sqlResult.getLong("time"),
|
||||||
|
sqlResult.getInt("securityKey"),
|
||||||
|
sqlResult.getString("viewerId"),
|
||||||
|
sqlResult.getString("sourceId"),
|
||||||
|
sqlResult.getString("message"),
|
||||||
|
sqlResult.getBoolean("wasRead"),
|
||||||
|
sqlResult.getBoolean("serverSync"));
|
||||||
|
String destId = sqlResult.getString("destId");
|
||||||
|
el.setDestId(destId==null ? null : UUID.fromString(destId));
|
||||||
|
|
||||||
|
int group = sqlResult.getInt("destGroup");
|
||||||
|
el.setDestGroup(sqlResult.wasNull()?null:group);
|
||||||
|
|
||||||
|
el.setDeleted(sqlResult.getBoolean("deleted"));
|
||||||
|
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<MPMessageElement> getAllUnsyncMessage() throws SQLException {
|
||||||
|
return getAll("serverSync = 0", "time ASC", null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<MPMessageElement> getAllUnreadForPlayer(UUID player) throws SQLException {
|
||||||
|
return getForPlayer(player, true, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<MPMessageElement> getOneDiscussionForPlayer(UUID player, Object discussion, Integer numberLast, boolean revert) throws SQLException {
|
||||||
|
if (player == null) return null;
|
||||||
|
if (discussion != null && !(discussion instanceof String) && !(discussion instanceof UUID)) return null;
|
||||||
|
if (discussion != null && discussion instanceof String && !PlayerFinder.isValidPlayerName(discussion.toString())) return null;
|
||||||
|
|
||||||
|
String where = "viewerId = '"+player+"'";
|
||||||
|
if (discussion == null)
|
||||||
|
where += " AND sourceId IS NULL AND destGroup IS NULL";
|
||||||
|
else if (discussion instanceof String)
|
||||||
|
where += " AND destGroup IN (SELECT id FROM "+ORM.getTable(MPGroupTable.class).getTableName()+" WHERE groupName LIKE '"+discussion+"')";
|
||||||
|
else if (discussion instanceof UUID && discussion.equals(player))
|
||||||
|
where += " AND destId LIKE '"+discussion+"' AND sourceId LIKE '"+discussion+"' AND destGroup IS NULL";
|
||||||
|
else // discussion instanceof UUID
|
||||||
|
where += " AND (destId LIKE '"+discussion+"' OR sourceId LIKE '"+discussion+"') AND destGroup IS NULL";
|
||||||
|
|
||||||
|
return getAll(where, (revert)?"time DESC":"time ASC", numberLast, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<MPMessageElement> getForPlayer(UUID player, boolean onlyUnread, Integer numberLast, boolean revert) throws SQLException {
|
||||||
|
if (player == null) return null;
|
||||||
|
|
||||||
|
String where = "viewerId = '"+player+"'";
|
||||||
|
if (onlyUnread)
|
||||||
|
where += " AND wasRead = 0";
|
||||||
|
|
||||||
|
return getAll(where, (revert)?"time DESC":"time ASC", numberLast, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
141
src/fr/pandacube/java/util/db/ModoHistoryElement.java
Normal file
141
src/fr/pandacube/java/util/db/ModoHistoryElement.java
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ModoHistoryElement extends SQLElement {
|
||||||
|
|
||||||
|
private String modoId = null;
|
||||||
|
private ActionType actionType;
|
||||||
|
private long time;
|
||||||
|
private String playerId;
|
||||||
|
private Long value = null;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
|
||||||
|
public ModoHistoryElement(UUID modo, ActionType type, UUID player, String message) {
|
||||||
|
super("pandacube_modo_history");
|
||||||
|
setModoId(modo);
|
||||||
|
setActionType(type);
|
||||||
|
setPlayerId(player);
|
||||||
|
setMessage(message);
|
||||||
|
time = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
ModoHistoryElement(int id, String modo, ActionType type, String player, String message) {
|
||||||
|
super("pandacube_modo_history", id);
|
||||||
|
setModoId((modo == null)?null:UUID.fromString(modo));
|
||||||
|
setActionType(type);
|
||||||
|
setPlayerId(UUID.fromString(player));
|
||||||
|
setMessage(message);
|
||||||
|
time = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
modoId,
|
||||||
|
actionType.name(),
|
||||||
|
String.valueOf(time),
|
||||||
|
playerId,
|
||||||
|
(value == null)?null:value.toString(),
|
||||||
|
message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"modoId",
|
||||||
|
"actionType",
|
||||||
|
"time",
|
||||||
|
"playerId",
|
||||||
|
"value",
|
||||||
|
"message"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public UUID getModoId() {
|
||||||
|
return modoId == null ? null : UUID.fromString(modoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModoId(UUID modo) {
|
||||||
|
this.modoId = modo == null ? null : modo.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ActionType getActionType() {
|
||||||
|
return actionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActionType(ActionType actionType) {
|
||||||
|
if (actionType == null) throw new IllegalArgumentException("le paramètre ne peut être null");
|
||||||
|
this.actionType = actionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne la durée de la sanction appliquée (en secondes), ou la somme d'argent retirée du compte
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value correspond soit à la durée de la sanction appliquée (en secondes), soit à la valeur de l'amende appliquée
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public void setValue(Long value) {
|
||||||
|
if (value != null && value.longValue() < 0) value = null;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public UUID getPlayerId() {
|
||||||
|
return UUID.fromString(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerId(UUID player) {
|
||||||
|
if (player == null) throw new IllegalArgumentException("le paramètre ne peut être null");
|
||||||
|
this.playerId = player.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
if (message == null) throw new IllegalArgumentException("le paramètre ne peut être null");
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(long time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public enum ActionType{
|
||||||
|
BAN, UNBAN, MUTE, UNMUTE, REPORT, KICK
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
src/fr/pandacube/java/util/db/ModoHistoryTable.java
Normal file
40
src/fr/pandacube/java/util/db/ModoHistoryTable.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import fr.pandacube.java.util.db.ModoHistoryElement.ActionType;
|
||||||
|
|
||||||
|
public class ModoHistoryTable extends SQLTable<ModoHistoryElement> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ModoHistoryTable() throws SQLException {
|
||||||
|
super("pandacube_modo_history");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "modoId CHAR(36) NULL," // null si c'est la console
|
||||||
|
+ "actionType ENUM('BAN', 'UNBAN', 'MUTE', 'UNMUTE', 'REPORT', 'KICK') NOT NULL,"
|
||||||
|
+ "time BIGINT NOT NULL,"
|
||||||
|
+ "playerId CHAR(36) NOT NULL,"
|
||||||
|
+ "value BIGINT NULL,"
|
||||||
|
+ "message VARCHAR(512) NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ModoHistoryElement getElementInstance(ResultSet sqlResult) throws SQLException {
|
||||||
|
ModoHistoryElement el = new ModoHistoryElement(
|
||||||
|
sqlResult.getInt("id"),
|
||||||
|
sqlResult.getString("modoId"),
|
||||||
|
ActionType.valueOf(sqlResult.getString("actionType")),
|
||||||
|
sqlResult.getString("playerId"),
|
||||||
|
sqlResult.getString("message"));
|
||||||
|
el.setValue(sqlResult.getLong("value"));
|
||||||
|
el.setTime(sqlResult.getLong("time"));
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
86
src/fr/pandacube/java/util/db/ORM.java
Normal file
86
src/fr/pandacube/java/util/db/ORM.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>ORM = Object-Relational Mapping</b><br/>
|
||||||
|
* Liste des tables avec leur classes :
|
||||||
|
* <ul>
|
||||||
|
* <li><code>LoginHistoryTable</code></li>
|
||||||
|
* <li><code>ModoHistoryTable</code></li>
|
||||||
|
* <li><code>StaffTicketTable</code></li>
|
||||||
|
* <li><code>MPMessageTable</code></li>
|
||||||
|
* <li><code>MPGroupTable</code></li>
|
||||||
|
* <li><code>MPGroupUserTable</code></li>
|
||||||
|
* <li><code>MPWebSessionTable</code></li>
|
||||||
|
* <li><code>PlayerIgnoreTable</code></li>
|
||||||
|
* </ul>
|
||||||
|
* @author Marc Baloup
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class ORM {
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
private static List<SQLTable> tables = new ArrayList<SQLTable>();
|
||||||
|
|
||||||
|
/* package */ static DBConnection connection;
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized static void init(DBConnection conn) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
connection = conn;
|
||||||
|
/*
|
||||||
|
* Les tables SQL sont à instancier ici !
|
||||||
|
*/
|
||||||
|
|
||||||
|
tables.add(new LoginHistoryTable());
|
||||||
|
|
||||||
|
tables.add(new ModoHistoryTable());
|
||||||
|
|
||||||
|
tables.add(new StaffTicketTable());
|
||||||
|
|
||||||
|
tables.add(new MPMessageTable());
|
||||||
|
tables.add(new MPGroupTable());
|
||||||
|
tables.add(new MPGroupUserTable());
|
||||||
|
tables.add(new PlayerTable());
|
||||||
|
|
||||||
|
tables.add(new PlayerIgnoreTable());
|
||||||
|
|
||||||
|
tables.add(new ShopStockTable());
|
||||||
|
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public synchronized static <T extends SQLTable> T getTable(Class<T> c) {
|
||||||
|
if (c == null) return null;
|
||||||
|
for (SQLTable table : tables) {
|
||||||
|
|
||||||
|
if (c.isAssignableFrom(table.getClass())) {
|
||||||
|
return c.cast(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private ORM() { } // rend la classe non instanciable
|
||||||
|
|
||||||
|
|
||||||
|
}
|
163
src/fr/pandacube/java/util/db/PlayerElement.java
Normal file
163
src/fr/pandacube/java/util/db/PlayerElement.java
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerElement extends SQLElement {
|
||||||
|
|
||||||
|
private String playerId;
|
||||||
|
private String token = null;
|
||||||
|
private String mailCheck = null;
|
||||||
|
private String password = null;
|
||||||
|
private String mail = null;
|
||||||
|
private String playerDisplayName;
|
||||||
|
private long firstTimeInGame;
|
||||||
|
private long timeWebRegister = 0;
|
||||||
|
private long lastTimeInGame = 0;
|
||||||
|
private long lastWebActivity = 0;
|
||||||
|
private String onlineInServer = null;
|
||||||
|
private String skinURL = null;
|
||||||
|
private boolean isVanish = false;
|
||||||
|
private Date birthday = null;
|
||||||
|
private int lastYearCelebratedBirthday = 0;
|
||||||
|
private Long banTimeout = null;
|
||||||
|
private Long muteTimeout = null;
|
||||||
|
private boolean isWhitelisted = false;
|
||||||
|
|
||||||
|
public PlayerElement(UUID pId, String dispName, long firstTimeIG, long lastWebAct, String onlineInServer) {
|
||||||
|
super("pandacube_player");
|
||||||
|
setPlayerId(pId);
|
||||||
|
setOnlineInServer(onlineInServer);
|
||||||
|
setLastWebActivity(lastWebAct);
|
||||||
|
setPlayerDisplayName(dispName);
|
||||||
|
setFirstTimeInGame(firstTimeIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PlayerElement(int id, String pId, String dispName, long firstTimeIG, long lastWebAct, String onlineInServer) {
|
||||||
|
super("pandacube_player", id);
|
||||||
|
setPlayerId(UUID.fromString(pId));
|
||||||
|
setOnlineInServer(onlineInServer);
|
||||||
|
setLastWebActivity(lastWebAct);
|
||||||
|
setPlayerDisplayName(dispName);
|
||||||
|
setFirstTimeInGame(firstTimeIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
playerId,
|
||||||
|
token,
|
||||||
|
mailCheck,
|
||||||
|
password,
|
||||||
|
mail,
|
||||||
|
playerDisplayName,
|
||||||
|
Long.toString(firstTimeInGame),
|
||||||
|
Long.toString(timeWebRegister),
|
||||||
|
Long.toString(lastTimeInGame),
|
||||||
|
Long.toString(lastWebActivity),
|
||||||
|
onlineInServer,
|
||||||
|
skinURL,
|
||||||
|
isVanish?"1":"0",
|
||||||
|
(birthday!=null)?birthday.toString():null,
|
||||||
|
Integer.toString(lastYearCelebratedBirthday),
|
||||||
|
(banTimeout!=null)?banTimeout.toString():null,
|
||||||
|
(muteTimeout!=null)?muteTimeout.toString():null,
|
||||||
|
isWhitelisted?"1":"0"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"playerId",
|
||||||
|
"token",
|
||||||
|
"mailCheck",
|
||||||
|
"password",
|
||||||
|
"mail",
|
||||||
|
"playerDisplayName",
|
||||||
|
"firstTimeInGame",
|
||||||
|
"timeWebRegister",
|
||||||
|
"lastTimeInGame",
|
||||||
|
"lastWebActivity",
|
||||||
|
"onlineInServer",
|
||||||
|
"skinURL",
|
||||||
|
"isVanish",
|
||||||
|
"birthday",
|
||||||
|
"lastYearCelebratedBirthday",
|
||||||
|
"banTimeout",
|
||||||
|
"muteTimeout",
|
||||||
|
"isWhitelisted"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getPlayerId() { return UUID.fromString(playerId); }
|
||||||
|
public UUID getToken() { return (token == null) ? null : UUID.fromString(token); }
|
||||||
|
public String getMailCheck() { return mailCheck; }
|
||||||
|
public String getPasswordHash() { return password; }
|
||||||
|
public String getMail() { return mail; }
|
||||||
|
public long getFirstTimeInGame() { return firstTimeInGame; }
|
||||||
|
public long getTimeWebRegister() { return timeWebRegister; }
|
||||||
|
public long getLastTimeInGame() { return lastTimeInGame; }
|
||||||
|
public long getLastWebActivity() { return lastWebActivity; }
|
||||||
|
public String getOnlineInServer() { return onlineInServer; }
|
||||||
|
public String getPlayerDisplayName() { return playerDisplayName; }
|
||||||
|
public String getSkinURL() { return skinURL; }
|
||||||
|
public boolean isVanish() { return isVanish; }
|
||||||
|
public Date getBirthday() { return birthday; }
|
||||||
|
public int getLastYearCelebratedBirthday() { return lastYearCelebratedBirthday; }
|
||||||
|
public Long getBanTimeout() { return banTimeout; }
|
||||||
|
public Long getMuteTimeout() { return muteTimeout; }
|
||||||
|
public boolean isWhitelisted() { return isWhitelisted; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setPlayerId(UUID pName) {
|
||||||
|
if (pName == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
playerId = pName.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(UUID t) {
|
||||||
|
if (t == null)
|
||||||
|
token = null;
|
||||||
|
else
|
||||||
|
token = t.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMailCheck(String mCheck) { mailCheck = mCheck; }
|
||||||
|
|
||||||
|
public void setPasswordHash(String pass) { password = pass; }
|
||||||
|
|
||||||
|
public void setMail(String m) { mail = m; }
|
||||||
|
|
||||||
|
public void setFirstTimeInGame(long time) { firstTimeInGame = time; }
|
||||||
|
|
||||||
|
public void setTimeWebRegister(long time) { timeWebRegister = time; }
|
||||||
|
|
||||||
|
public void setLastTimeInGame(long time) { lastTimeInGame = time; }
|
||||||
|
|
||||||
|
public void setLastWebActivity(long time) { lastWebActivity = time; }
|
||||||
|
|
||||||
|
public void setOnlineInServer(String onlineInServer) { this.onlineInServer = onlineInServer; }
|
||||||
|
|
||||||
|
public void setSkinURL(String skinURL) { this.skinURL = skinURL; }
|
||||||
|
|
||||||
|
public void setPlayerDisplayName(String dispName) {
|
||||||
|
if (dispName == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
playerDisplayName = dispName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVanish(boolean v) { isVanish = v; }
|
||||||
|
|
||||||
|
public void setBirthday(Date b) { birthday = b; }
|
||||||
|
|
||||||
|
public void setLastYearCelebratedBirthday(int y) { lastYearCelebratedBirthday = y; }
|
||||||
|
|
||||||
|
public void setBanTimeout(Long banT) { banTimeout = banT; }
|
||||||
|
|
||||||
|
public void setMuteTimeout(Long muteT) { muteTimeout = muteT; }
|
||||||
|
|
||||||
|
public void setWhitelisted(boolean w) { isWhitelisted = w; }
|
||||||
|
|
||||||
|
}
|
66
src/fr/pandacube/java/util/db/PlayerIgnoreElement.java
Normal file
66
src/fr/pandacube/java/util/db/PlayerIgnoreElement.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerIgnoreElement extends SQLElement {
|
||||||
|
|
||||||
|
private String ignore;
|
||||||
|
private String ignored;
|
||||||
|
|
||||||
|
|
||||||
|
public PlayerIgnoreElement(UUID ignore, UUID ignored) {
|
||||||
|
super("pandacube_player_ignore");
|
||||||
|
setIgnore(ignore);
|
||||||
|
setIgnored(ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected PlayerIgnoreElement(int id, String ignore, String ignored) {
|
||||||
|
super("pandacube_player_ignore", id);
|
||||||
|
this.ignore = ignore;
|
||||||
|
this.ignored = ignored;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
ignore,
|
||||||
|
ignored
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"ignorer",
|
||||||
|
"ignored"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UUID getIgnore() {
|
||||||
|
return UUID.fromString(ignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setIgnore(UUID i) {
|
||||||
|
if (i == null)
|
||||||
|
throw new IllegalArgumentException("i can't be null");
|
||||||
|
ignore = i.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UUID getIgnored() {
|
||||||
|
return UUID.fromString(ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setIgnored(UUID i) {
|
||||||
|
if (i == null)
|
||||||
|
throw new IllegalArgumentException("i can't be null");
|
||||||
|
ignored = i.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
79
src/fr/pandacube/java/util/db/PlayerIgnoreTable.java
Normal file
79
src/fr/pandacube/java/util/db/PlayerIgnoreTable.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerIgnoreTable extends SQLTable<PlayerIgnoreElement> {
|
||||||
|
|
||||||
|
public PlayerIgnoreTable() throws SQLException {
|
||||||
|
super("pandacube_player_ignore");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "ignorer CHAR(36) NOT NULL,"
|
||||||
|
+ "ignored CHAR(36) NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PlayerIgnoreElement getElementInstance(ResultSet sqlResult) throws SQLException {
|
||||||
|
return new PlayerIgnoreElement(sqlResult.getInt("id"),
|
||||||
|
sqlResult.getString("ignorer"),
|
||||||
|
sqlResult.getString("ignored"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<UUID> getListIgnoredPlayer(UUID ignore) throws SQLException {
|
||||||
|
if (ignore == null)
|
||||||
|
throw new IllegalArgumentException("ignore can't be null");
|
||||||
|
|
||||||
|
List<PlayerIgnoreElement> dbIgnored = getAll("ignorer = '"+ignore+"'", "id", null, null);
|
||||||
|
|
||||||
|
List<UUID> ret = new ArrayList<UUID>();
|
||||||
|
|
||||||
|
for (PlayerIgnoreElement el : dbIgnored) {
|
||||||
|
ret.add(el.getIgnored());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isPlayerIgnoringPlayer(UUID ignore, UUID ignored) throws SQLException {
|
||||||
|
if (ignore == null)
|
||||||
|
throw new IllegalArgumentException("ignore can't be null");
|
||||||
|
if (ignored == null)
|
||||||
|
throw new IllegalArgumentException("ignored can't be null");
|
||||||
|
|
||||||
|
return getFirst("ignorer = '"+ignore+"' AND ignored = '"+ignored+"'", "id") != null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setPlayerIgnorePlayer(UUID ignore, UUID ignored, boolean set) throws SQLException {
|
||||||
|
if (ignore == null)
|
||||||
|
throw new IllegalArgumentException("ignore can't be null");
|
||||||
|
if (ignored == null)
|
||||||
|
throw new IllegalArgumentException("ignored can't be null");
|
||||||
|
if (ignore.equals(ignored)) // on ne peut pas s'auto ignorer
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerIgnoreElement el = getFirst("ignorer = '"+ignore+"' AND ignored = '"+ignored+"'", "id");
|
||||||
|
|
||||||
|
if (set && el == null) {
|
||||||
|
el = new PlayerIgnoreElement(ignore, ignored);
|
||||||
|
el.save();
|
||||||
|
}
|
||||||
|
else if (!set && el != null) {
|
||||||
|
el.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
70
src/fr/pandacube/java/util/db/PlayerTable.java
Normal file
70
src/fr/pandacube/java/util/db/PlayerTable.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerTable extends SQLTable<PlayerElement> {
|
||||||
|
|
||||||
|
public PlayerTable() throws SQLException {
|
||||||
|
super("pandacube_player");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "playerId CHAR(36) NOT NULL,"
|
||||||
|
+ "token CHAR(36) NULL,"
|
||||||
|
+ "mailCheck VARCHAR(255) NULL,"
|
||||||
|
+ "password VARCHAR(255) NULL,"
|
||||||
|
+ "mail VARCHAR(255) NULL,"
|
||||||
|
+ "playerDisplayName VARCHAR(255) NOT NULL,"
|
||||||
|
+ "firstTimeInGame BIGINT NOT NULL,"
|
||||||
|
+ "timeWebRegister BIGINT NULL,"
|
||||||
|
+ "lastTimeInGame BIGINT NULL,"
|
||||||
|
+ "lastWebActivity BIGINT NOT NULL,"
|
||||||
|
+ "onlineInServer VARCHAR(32) NULL,"
|
||||||
|
+ "skinURL VARCHAR(255) NULL,"
|
||||||
|
+ "isVanish TINYINT NULL,"
|
||||||
|
+ "birthday DATE NULL,"
|
||||||
|
+ "lastYearCelebratedBirthday INT NOT NULL DEFAULT 0,"
|
||||||
|
+ "banTimeout BIGINT NULL,"
|
||||||
|
+ "muteTimeout BIGINT NULL,"
|
||||||
|
+ "isWhitelisted TINYINT NOT NULL DEFAULT 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PlayerElement getElementInstance(ResultSet sqlResult)
|
||||||
|
throws SQLException {
|
||||||
|
PlayerElement el = new PlayerElement(
|
||||||
|
sqlResult.getInt("id"),
|
||||||
|
sqlResult.getString("playerId"),
|
||||||
|
sqlResult.getString("playerDisplayName"),
|
||||||
|
sqlResult.getLong("firstTimeInGame"),
|
||||||
|
sqlResult.getLong("lastWebActivity"),
|
||||||
|
sqlResult.getString("onlineInServer"));
|
||||||
|
String token = sqlResult.getString("token");
|
||||||
|
el.setToken((token == null) ? null : UUID.fromString(token));
|
||||||
|
el.setMailCheck(sqlResult.getString("mailCheck"));
|
||||||
|
el.setPasswordHash(sqlResult.getString("password"));
|
||||||
|
el.setMail(sqlResult.getString("mail"));
|
||||||
|
el.setFirstTimeInGame(sqlResult.getLong("firstTimeInGame"));
|
||||||
|
el.setTimeWebRegister(sqlResult.getLong("timeWebRegister"));
|
||||||
|
el.setLastTimeInGame(sqlResult.getLong("lastTimeInGame"));
|
||||||
|
el.setSkinURL(sqlResult.getString("skinURL"));
|
||||||
|
el.setVanish(sqlResult.getBoolean("isVanish"));
|
||||||
|
el.setBirthday(sqlResult.getDate("birthday"));
|
||||||
|
el.setLastYearCelebratedBirthday(sqlResult.getInt("lastYearCelebratedBirthday"));
|
||||||
|
|
||||||
|
long longVal;
|
||||||
|
|
||||||
|
longVal = sqlResult.getLong("banTimeout");
|
||||||
|
el.setBanTimeout(sqlResult.wasNull()?null:longVal);
|
||||||
|
longVal = sqlResult.getLong("muteTimeout");
|
||||||
|
el.setMuteTimeout(sqlResult.wasNull()?null:longVal);
|
||||||
|
|
||||||
|
el.setWhitelisted(sqlResult.getBoolean("isWhitelisted"));
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
160
src/fr/pandacube/java/util/db/SQLElement.java
Normal file
160
src/fr/pandacube/java/util/db/SQLElement.java
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
public abstract class SQLElement {
|
||||||
|
|
||||||
|
DBConnection db = ORM.connection;
|
||||||
|
|
||||||
|
|
||||||
|
private boolean saved = false;
|
||||||
|
|
||||||
|
protected final String tableName;
|
||||||
|
|
||||||
|
// champ relatif aux données
|
||||||
|
private int id = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SQLElement(String name) {
|
||||||
|
tableName = name;
|
||||||
|
saved = false;
|
||||||
|
}
|
||||||
|
protected SQLElement(String name, int id) {
|
||||||
|
tableName = name;
|
||||||
|
this.id = id;
|
||||||
|
saved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Connection conn;
|
||||||
|
conn = db.getConnection();
|
||||||
|
|
||||||
|
String[] fields = getFieldsName(), values = getValues();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (saved)
|
||||||
|
{ // mettre à jour les valeurs dans la base
|
||||||
|
String sql = "";
|
||||||
|
for (int i=0; i<fields.length && i<values.length; i++)
|
||||||
|
{
|
||||||
|
sql += fields[i]+" = ? ,";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sql.length() > 0)
|
||||||
|
sql = sql.substring(0, sql.length()-1);
|
||||||
|
|
||||||
|
PreparedStatement st = conn.prepareStatement("UPDATE "+tableName+" SET "+sql+" WHERE id="+id);
|
||||||
|
try {
|
||||||
|
for (int i=0; i<fields.length && i<values.length; i++)
|
||||||
|
{
|
||||||
|
st.setString(i+1, values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
st.executeUpdate();
|
||||||
|
} finally {
|
||||||
|
st.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // ajouter dans la base
|
||||||
|
String concat_vals = "";
|
||||||
|
String concat_fields = StringUtils.join(fields, ',');
|
||||||
|
for (int i=0; i<fields.length && i<values.length; i++)
|
||||||
|
{
|
||||||
|
if (i!=0) concat_vals += ",";
|
||||||
|
concat_vals += " ? ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PreparedStatement st = conn.prepareStatement("INSERT INTO "+tableName+" ("+concat_fields+") VALUES ("+concat_vals+")", Statement.RETURN_GENERATED_KEYS);
|
||||||
|
try {
|
||||||
|
for (int i=0; i<fields.length && i<values.length; i++)
|
||||||
|
{
|
||||||
|
st.setString(i+1, values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
st.executeUpdate();
|
||||||
|
|
||||||
|
ResultSet rs = st.getGeneratedKeys();
|
||||||
|
try {
|
||||||
|
if(rs.next())
|
||||||
|
{
|
||||||
|
id = rs.getInt(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
saved = true;
|
||||||
|
} finally {
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
st.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (saved)
|
||||||
|
{ // supprimer la ligne de la base
|
||||||
|
PreparedStatement st = db.getConnection().prepareStatement("DELETE FROM "+tableName+" WHERE id="+id);
|
||||||
|
try {
|
||||||
|
st.executeUpdate();
|
||||||
|
saved = false;
|
||||||
|
} finally {
|
||||||
|
st.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
if (!saved)
|
||||||
|
throw new IllegalStateException("Ne peut pas fournir l'ID d'un élément non sauvegardé");
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère la liste des valeurs des champs de la table correspondante, excepté
|
||||||
|
* le champ <code>id</code>
|
||||||
|
* @return les valeurs des champs sous la forme de chaine de caractères
|
||||||
|
*/
|
||||||
|
protected abstract String[] getValues();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère la liste des noms des champs de la table correspondante, excepté
|
||||||
|
* le champ <code>id</code>
|
||||||
|
* @return les noms des champs sous la forme de chaine de caractères
|
||||||
|
*/
|
||||||
|
protected abstract String[] getFieldsName();
|
||||||
|
}
|
140
src/fr/pandacube/java/util/db/SQLTable.java
Normal file
140
src/fr/pandacube/java/util/db/SQLTable.java
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class SQLTable<T extends SQLElement> {
|
||||||
|
|
||||||
|
DBConnection db = ORM.connection;
|
||||||
|
|
||||||
|
private final String tableName;
|
||||||
|
|
||||||
|
|
||||||
|
public SQLTable(String name) throws SQLException {
|
||||||
|
tableName = name;
|
||||||
|
|
||||||
|
if (!tableExist())
|
||||||
|
createTable();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void createTable() throws SQLException {
|
||||||
|
Statement stmt = db.getConnection().createStatement();
|
||||||
|
String sql = "CREATE TABLE IF NOT EXISTS "+tableName+" " +
|
||||||
|
"("+createTableParameters()+")";
|
||||||
|
try {
|
||||||
|
stmt.executeUpdate(sql);
|
||||||
|
} finally {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean tableExist() throws SQLException {
|
||||||
|
ResultSet set = null;
|
||||||
|
boolean exist = false;
|
||||||
|
try {
|
||||||
|
set = db.getConnection().getMetaData().getTables(null, null, tableName, null);
|
||||||
|
exist = set.next();
|
||||||
|
} finally {
|
||||||
|
if (set != null)
|
||||||
|
set.close();
|
||||||
|
}
|
||||||
|
return exist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne une chaine de caractère qui sera inclu dans la requête SQL de création de la table.
|
||||||
|
* La requête est de la forme : <code>CRATE TABLE tableName ();</code>
|
||||||
|
* La chaine retournée sera ajoutée entre les parenthèses.
|
||||||
|
*/
|
||||||
|
protected abstract String createTableParameters();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crée une instance de l'élément courant se trouvant dans le resultSet passé en paramètre
|
||||||
|
* @param sqlResult le set de résultat, déjà positionné sur un élément. Ne surtout pas appeler la méthode next() !
|
||||||
|
* @return
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
protected abstract T getElementInstance(ResultSet sqlResult) throws SQLException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getTableName() {
|
||||||
|
return tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public T get(int id) throws SQLException {
|
||||||
|
T elementInstance = null;
|
||||||
|
Statement stmt = db.getConnection().createStatement();
|
||||||
|
try {
|
||||||
|
String sql = "SELECT * FROM "+tableName+" WHERE id = "+id+";";
|
||||||
|
|
||||||
|
ResultSet set = stmt.executeQuery(sql);
|
||||||
|
try {
|
||||||
|
if (set.next())
|
||||||
|
elementInstance = getElementInstance(set);
|
||||||
|
} finally {
|
||||||
|
set.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
return elementInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<T> getAll() throws SQLException {
|
||||||
|
return getAll(null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public T getFirst(String where, String orderBy) throws SQLException {
|
||||||
|
List<T> elts = getAll(where, orderBy, 1, null);
|
||||||
|
return (elts.size() == 0)? null : elts.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<T> getAll(String where, String orderBy, Integer limit, Integer offset) throws SQLException {
|
||||||
|
Statement stmt = db.getConnection().createStatement();
|
||||||
|
String sql = "SELECT * FROM "+tableName;
|
||||||
|
|
||||||
|
if (where != null)
|
||||||
|
sql += " WHERE "+where;
|
||||||
|
if (orderBy != null)
|
||||||
|
sql += " ORDER BY "+orderBy;
|
||||||
|
if (limit != null)
|
||||||
|
sql += " LIMIT "+limit;
|
||||||
|
if (offset != null)
|
||||||
|
sql += " OFFSET "+offset;
|
||||||
|
sql += ";";
|
||||||
|
|
||||||
|
List<T> elmts = new ArrayList<T>();
|
||||||
|
try {
|
||||||
|
ResultSet set = stmt.executeQuery(sql);
|
||||||
|
try {
|
||||||
|
while (set.next())
|
||||||
|
elmts.add(getElementInstance(set));
|
||||||
|
} finally {
|
||||||
|
set.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
return elmts;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
src/fr/pandacube/java/util/db/ShopStockElement.java
Normal file
74
src/fr/pandacube/java/util/db/ShopStockElement.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
public class ShopStockElement extends SQLElement {
|
||||||
|
|
||||||
|
private String material;
|
||||||
|
private short damage = 0;
|
||||||
|
private double quantity;
|
||||||
|
private String server;
|
||||||
|
|
||||||
|
|
||||||
|
public ShopStockElement(String m, short d, double q, String s) {
|
||||||
|
super("pandacube_shop_stock");
|
||||||
|
setMaterial(m);
|
||||||
|
setDamage(d);
|
||||||
|
setQuantity(q);
|
||||||
|
setServer(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ShopStockElement(int id, String m, short d, double q, String s) {
|
||||||
|
super("pandacube_shop_stock", id);
|
||||||
|
setMaterial(m);
|
||||||
|
setDamage(d);
|
||||||
|
setQuantity(q);
|
||||||
|
setServer(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
material,
|
||||||
|
Short.toString(damage),
|
||||||
|
Double.toString(quantity),
|
||||||
|
server
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"material",
|
||||||
|
"damage",
|
||||||
|
"quantity",
|
||||||
|
"server"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMaterial() { return material; }
|
||||||
|
|
||||||
|
public void setMaterial(String m) {
|
||||||
|
if (m == null) throw new IllegalArgumentException("Material can't be null");
|
||||||
|
material = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getDamage() { return damage; }
|
||||||
|
|
||||||
|
public void setDamage(short d) {
|
||||||
|
damage = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getQuantity() { return quantity; }
|
||||||
|
|
||||||
|
public void setQuantity(double q) {
|
||||||
|
if (q < 0) q = 0;
|
||||||
|
quantity = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServer() { return server; }
|
||||||
|
|
||||||
|
public void setServer(String s) {
|
||||||
|
if (s == null) throw new IllegalArgumentException("Server can't be null");
|
||||||
|
server = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
src/fr/pandacube/java/util/db/ShopStockTable.java
Normal file
30
src/fr/pandacube/java/util/db/ShopStockTable.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class ShopStockTable extends SQLTable<ShopStockElement> {
|
||||||
|
|
||||||
|
public ShopStockTable() throws SQLException {
|
||||||
|
super("pandacube_shop_stock");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "material varchar(50) NOT NULL,"
|
||||||
|
+ "damage int(11) NOT NULL DEFAULT '0',"
|
||||||
|
+ "quantity double NOT NULL,"
|
||||||
|
+ "server varchar(50) NOT NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ShopStockElement getElementInstance(ResultSet sqlResult) throws SQLException {
|
||||||
|
return new ShopStockElement(sqlResult.getInt("id"),
|
||||||
|
sqlResult.getString("material"),
|
||||||
|
sqlResult.getShort("damage"),
|
||||||
|
sqlResult.getDouble("quantity"),
|
||||||
|
sqlResult.getString("server"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
77
src/fr/pandacube/java/util/db/StaffTicketElement.java
Normal file
77
src/fr/pandacube/java/util/db/StaffTicketElement.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class StaffTicketElement extends SQLElement {
|
||||||
|
|
||||||
|
|
||||||
|
private String playerId;
|
||||||
|
private String message;
|
||||||
|
private long creationTime;
|
||||||
|
private String staffPlayerId = null;
|
||||||
|
|
||||||
|
|
||||||
|
public StaffTicketElement(UUID pId, String m, long creaTime) {
|
||||||
|
super("pandacube_staff_ticket");
|
||||||
|
setPlayerId(pId);
|
||||||
|
setMessage(m);
|
||||||
|
setCreationTime(creaTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
protected StaffTicketElement(int id, String pId, String m, long creaTime) {
|
||||||
|
super("pandacube_staff_ticket", id);
|
||||||
|
setPlayerId(UUID.fromString(pId));
|
||||||
|
setMessage(m);
|
||||||
|
setCreationTime(creaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getValues() {
|
||||||
|
return new String[] {
|
||||||
|
playerId,
|
||||||
|
message,
|
||||||
|
Long.toString(creationTime),
|
||||||
|
staffPlayerId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getFieldsName() {
|
||||||
|
return new String[] {
|
||||||
|
"playerId",
|
||||||
|
"message",
|
||||||
|
"creationTime",
|
||||||
|
"staffPlayerId"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public UUID getPlayerId() {
|
||||||
|
return UUID.fromString(playerId);
|
||||||
|
}
|
||||||
|
public void setPlayerId(UUID pId) {
|
||||||
|
if (pId == null) throw new IllegalArgumentException("playerName can't be null");
|
||||||
|
this.playerId = pId.toString();
|
||||||
|
}
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
public void setMessage(String message) {
|
||||||
|
if (message == null) throw new IllegalArgumentException("message can't be null");
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
public long getCreationTime() {
|
||||||
|
return creationTime;
|
||||||
|
}
|
||||||
|
public void setCreationTime(long creationTime) {
|
||||||
|
this.creationTime = creationTime;
|
||||||
|
}
|
||||||
|
public UUID getStaffPlayer() {
|
||||||
|
if (staffPlayerId == null) return null;
|
||||||
|
return UUID.fromString(staffPlayerId);
|
||||||
|
}
|
||||||
|
public void setStaffPlayer(UUID staffId) {
|
||||||
|
if (staffId == null) staffPlayerId = null;
|
||||||
|
else staffPlayerId = staffId.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
37
src/fr/pandacube/java/util/db/StaffTicketTable.java
Normal file
37
src/fr/pandacube/java/util/db/StaffTicketTable.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package fr.pandacube.java.util.db;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class StaffTicketTable extends SQLTable<StaffTicketElement> {
|
||||||
|
|
||||||
|
|
||||||
|
public StaffTicketTable() throws SQLException {
|
||||||
|
super("pandacube_staff_ticket");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createTableParameters() {
|
||||||
|
return "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||||
|
+ "playerId CHAR(36) NOT NULL,"
|
||||||
|
+ "message VARCHAR(1024) NOT NULL,"
|
||||||
|
+ "creationTime BIGINT NOT NULL,"
|
||||||
|
+ "staffPlayerId CHAR(36) NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected StaffTicketElement getElementInstance(ResultSet sqlResult)
|
||||||
|
throws SQLException {
|
||||||
|
StaffTicketElement el = new StaffTicketElement(
|
||||||
|
sqlResult.getInt("id"),
|
||||||
|
sqlResult.getString("playerId"),
|
||||||
|
sqlResult.getString("message"),
|
||||||
|
sqlResult.getLong("creationTime"));
|
||||||
|
String staffId = sqlResult.getString("staffPlayerId");
|
||||||
|
el.setStaffPlayer((staffId == null) ? null : UUID.fromString(staffId));
|
||||||
|
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.client;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public abstract class AbstractRequest {
|
||||||
|
|
||||||
|
private final String pass;
|
||||||
|
private String command;
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
|
||||||
|
protected AbstractRequest(String cmd, String p) {
|
||||||
|
if (cmd == null || cmd.isEmpty()) throw new IllegalArgumentException("Un message doit-être défini");
|
||||||
|
command = cmd;
|
||||||
|
pass = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void setData(String d) {
|
||||||
|
if (d == null) d = "";
|
||||||
|
data = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void sendPacket(PrintStream out) {
|
||||||
|
out.print(pass+"\n");
|
||||||
|
out.print(command+"\n");
|
||||||
|
out.print(data.getBytes().length+"\n");
|
||||||
|
out.print(data);
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class NetworkAPISender {
|
||||||
|
|
||||||
|
public static ResponseAnalyser sendRequest(InetSocketAddress cible, AbstractRequest request) throws IOException {
|
||||||
|
Socket s = new Socket(cible.getAddress(), cible.getPort());
|
||||||
|
|
||||||
|
PrintStream out = new PrintStream(s.getOutputStream());
|
||||||
|
|
||||||
|
request.sendPacket(out);
|
||||||
|
s.shutdownOutput();
|
||||||
|
|
||||||
|
ResponseAnalyser response = new ResponseAnalyser(s);
|
||||||
|
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.client;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class ResponseAnalyser {
|
||||||
|
/**
|
||||||
|
* Indique si la requête s'est bien exécutée (l'entête de la réponse est 'ok')
|
||||||
|
*/
|
||||||
|
public final boolean good;
|
||||||
|
|
||||||
|
|
||||||
|
public final String data;
|
||||||
|
|
||||||
|
|
||||||
|
public ResponseAnalyser(Socket socket) throws IOException {
|
||||||
|
if (socket == null || socket.isClosed() || socket.isInputShutdown()) throw new IllegalArgumentException("le socket doit être non null et doit être ouvert sur le flux d'entrée");
|
||||||
|
|
||||||
|
// on lis la réponse
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
|
||||||
|
String line;
|
||||||
|
|
||||||
|
|
||||||
|
// lecture de la première ligne
|
||||||
|
line = in.readLine();
|
||||||
|
good = line.equalsIgnoreCase("OK");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// lecture de la deuxième ligne
|
||||||
|
line = in.readLine();
|
||||||
|
|
||||||
|
int data_size = 0;
|
||||||
|
try {
|
||||||
|
data_size = Integer.parseInt(line);
|
||||||
|
} catch (NumberFormatException e) { throw new RuntimeException("Réponse mal formée : la deuxième ligne doit-être un nombre entier"); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// lecture du reste
|
||||||
|
StringBuilder sB_data = new StringBuilder();
|
||||||
|
char[] c = new char[100];
|
||||||
|
int nbC = 0;
|
||||||
|
while((nbC = in.read(c)) != -1)
|
||||||
|
sB_data.append(c, 0, nbC);
|
||||||
|
data = sB_data.toString();
|
||||||
|
|
||||||
|
if (data.getBytes().length != data_size)
|
||||||
|
throw new RuntimeException("Réponse mal formée : "+data_size+" caractères annoncée dans la requête, mais "+data.getBytes().length+" s'y trouvent.");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public abstract class AbstractRequestExecutor {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public final String command;
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractRequestExecutor(String cmd, NetworkAPIListener napiListener) {
|
||||||
|
command = cmd.toLowerCase();
|
||||||
|
napiListener.registerRequestExecutor(command, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void execute(String data, Socket socket) throws IOException {
|
||||||
|
if (socket == null || socket.isClosed() || socket.isOutputShutdown()) throw new IllegalArgumentException("le socket doit être non null et doit être ouvert sur le flux d'entrée");
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Response rep = run(socket.getInetAddress(), data);
|
||||||
|
rep.sendPacket(new PrintStream(socket.getOutputStream()));
|
||||||
|
|
||||||
|
} catch(Exception e) {
|
||||||
|
new Response(false, e.toString()).sendPacket(new PrintStream(socket.getOutputStream()));
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param data La représentation sous forme de String des données envoyés dans la requête
|
||||||
|
* @return La réponse à retourner au client
|
||||||
|
*/
|
||||||
|
protected abstract Response run(InetAddress source, String data);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface permettant de gérer l'exécution asynchrone d'un PacketExecutor.
|
||||||
|
* @author Marc Baloup
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface NAPIExecutionHandler {
|
||||||
|
|
||||||
|
public void handleRun(Runnable executor);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class NetworkAPIListener implements Runnable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private int port = 0;
|
||||||
|
String pass;
|
||||||
|
private ServerSocket serverSocket;
|
||||||
|
private HashMap<String, AbstractRequestExecutor> requestExecutors = new HashMap<String, AbstractRequestExecutor>();
|
||||||
|
private String name;
|
||||||
|
private NAPIExecutionHandler nAPIExecutionHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instencie le côté serveur du NetworkAPI
|
||||||
|
* @param n nom du networkAPI (permet l'identification dans les logs)
|
||||||
|
* @param p le port d'écoute
|
||||||
|
* @param pa le mot de passe réseau
|
||||||
|
* @param peh PacketExecutionHandler permettant de prendre en charge l'exécution asynchrone d'une requête reçu pas un client
|
||||||
|
*/
|
||||||
|
public NetworkAPIListener(String n, int p, String pa, NAPIExecutionHandler peh) {
|
||||||
|
port = p;
|
||||||
|
pass = pa;
|
||||||
|
name = n;
|
||||||
|
nAPIExecutionHandler = peh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
serverSocket = new ServerSocket(port);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("NetworkAPI '"+name+"' à l'écoute sur le port "+port);
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// réception des connexion client
|
||||||
|
while (!serverSocket.isClosed()) {
|
||||||
|
Socket socketClient = serverSocket.accept();
|
||||||
|
nAPIExecutionHandler.handleRun(new PacketExecutor(socketClient, this));
|
||||||
|
}
|
||||||
|
} catch(IOException e) { }
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
if (!serverSocket.isClosed())
|
||||||
|
serverSocket.close();
|
||||||
|
} catch (IOException e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("NetworkAPI '"+name+"' ferme le port "+port);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ferme le ServerSocket. Ceci provoque l'arrêt du thread associé à l'instance de la classe
|
||||||
|
*/
|
||||||
|
public synchronized void closeServerSocket() {
|
||||||
|
if (serverSocket != null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
serverSocket.close();
|
||||||
|
} catch (IOException e) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int getPort() { return port; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void registerRequestExecutor(String command, AbstractRequestExecutor executor) {
|
||||||
|
requestExecutors.put(command, executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractRequestExecutor getRequestExecutor(String command) {
|
||||||
|
return requestExecutors.get(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getCommandList() {
|
||||||
|
return Arrays.toString(requestExecutors.keySet().toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prends en charge un socket client et le transmet au gestionnaire de paquet correspondant.<br/>
|
||||||
|
* La connexion est fermée après chaque requête du client (règle pouvant évoluer)
|
||||||
|
* @author Marc Baloup
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PacketExecutor implements Runnable {
|
||||||
|
private Socket socket;
|
||||||
|
private NetworkAPIListener networkAPIListener;
|
||||||
|
|
||||||
|
public PacketExecutor(Socket s, NetworkAPIListener napiListener) {
|
||||||
|
socket = s;
|
||||||
|
networkAPIListener = napiListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// analyse de la requête
|
||||||
|
RequestAnalyser analyse = new RequestAnalyser(socket, networkAPIListener);
|
||||||
|
|
||||||
|
|
||||||
|
AbstractRequestExecutor executor = networkAPIListener.getRequestExecutor(analyse.command);
|
||||||
|
|
||||||
|
executor.execute(analyse.data, socket);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch(Throwable e) {
|
||||||
|
Response rep = new Response();
|
||||||
|
rep.good = false;
|
||||||
|
rep.data = e.toString();
|
||||||
|
try {
|
||||||
|
rep.sendPacket(new PrintStream(socket.getOutputStream()));
|
||||||
|
} catch (IOException e1) { }
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
socket.close();
|
||||||
|
} catch (Exception e) { }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.server;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class RequestAnalyser {
|
||||||
|
|
||||||
|
private NetworkAPIListener networkAPIListener;
|
||||||
|
public final String command;
|
||||||
|
public final String data;
|
||||||
|
|
||||||
|
public RequestAnalyser(Socket socket, NetworkAPIListener napiListener) throws IOException, BadRequestException {
|
||||||
|
if (socket == null || socket.isClosed() || socket.isInputShutdown() || napiListener == null) throw new IllegalArgumentException("le socket doit être non null et doit être ouvert sur le flux d'entrée et napiListener ne doit pas être null");
|
||||||
|
|
||||||
|
networkAPIListener = napiListener;
|
||||||
|
|
||||||
|
// on lis la réponse
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
|
||||||
|
String line;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// lecture de la première ligne
|
||||||
|
line = in.readLine();
|
||||||
|
if (line == null || !line.equals(networkAPIListener.pass))
|
||||||
|
throw new BadRequestException("wrong_password");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// lecture de la deuxième ligne
|
||||||
|
line = in.readLine();
|
||||||
|
if (line == null || networkAPIListener.getRequestExecutor(line) == null)
|
||||||
|
throw new BadRequestException("command_not_exists");
|
||||||
|
command = line;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// lecture de la troisième ligne
|
||||||
|
line = in.readLine();
|
||||||
|
|
||||||
|
int data_size = 0;
|
||||||
|
try {
|
||||||
|
data_size = Integer.parseInt(line);
|
||||||
|
} catch (NumberFormatException e) { throw new BadRequestException("wrong_data_size_format"); }
|
||||||
|
|
||||||
|
|
||||||
|
// lecture du reste
|
||||||
|
StringBuilder sB_data = new StringBuilder();
|
||||||
|
char[] c = new char[100];
|
||||||
|
int nbC = 0;
|
||||||
|
while((nbC = in.read(c)) != -1)
|
||||||
|
sB_data.append(c, 0, nbC);
|
||||||
|
|
||||||
|
data = sB_data.toString();
|
||||||
|
|
||||||
|
if (data.getBytes().length != data_size)
|
||||||
|
throw new BadRequestException("wrong_data_size");
|
||||||
|
|
||||||
|
|
||||||
|
socket.shutdownInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class BadRequestException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public BadRequestException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
32
src/fr/pandacube/java/util/network_api/server/Response.java
Normal file
32
src/fr/pandacube/java/util/network_api/server/Response.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.server;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class Response {
|
||||||
|
public boolean good = true;
|
||||||
|
public String data = "";
|
||||||
|
|
||||||
|
|
||||||
|
public Response(boolean good, String data) {
|
||||||
|
this.good = good;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit une réponse positive avec aucune donnée. Équivaut à
|
||||||
|
* <code>new Response(true, "")</code>
|
||||||
|
*/
|
||||||
|
public Response() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void sendPacket(PrintStream out) {
|
||||||
|
|
||||||
|
if (data == null) data = "";
|
||||||
|
|
||||||
|
out.print((good?"OK":"ERROR")+"\n");
|
||||||
|
out.print(data.getBytes().length+"\n");
|
||||||
|
out.print(data);
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package fr.pandacube.java.util.network_api.server;
|
||||||
|
|
||||||
|
public class ThreadNAPIExecutionHandler implements NAPIExecutionHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRun(Runnable executor) {
|
||||||
|
new Thread(executor).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user