Création de la librairie Java PandacubeUtil

Utilisé par PandacubeBungee et PandacubeSpigot
This commit is contained in:
Marc Baloup 2016-02-16 20:07:51 +01:00
commit 6bc15b24f6
60 changed files with 5178 additions and 0 deletions

10
.classpath Normal file
View 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
View File

@ -0,0 +1 @@
convertToBungeePerms.txt

17
.project Normal file
View 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
View 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>

1
manifest Normal file
View File

@ -0,0 +1 @@
Manifest-Version: 1.0

4
resources/bungee.yml Normal file
View 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
View File

@ -0,0 +1,4 @@
name: PandacubeUtil
main: fr.pandacube.java.SpigotMain
version: 1.0-beta1
author: Marc Baloup (marcbal)

View 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();
}
}

View 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;
}
}

View 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;
}
}

View File

@ -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);
}
}

View 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);
}
}

View 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() {
}
}

View File

@ -0,0 +1,12 @@
package fr.pandacube.java;
import org.bukkit.plugin.java.JavaPlugin;
public class SpigotMain extends JavaPlugin {
@Override
public void onLoad() {
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,7 @@
package fr.pandacube.java.util;
@FunctionalInterface
public interface Callback<T> {
public void done(T arg);
}

View 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)];
}
}

View 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);
} // */
}

View 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";
}
}

View 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;
}
}

View 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}");
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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) { }
}
}

View 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
}
}

View 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;
}
}

View 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);
}
}

View 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"));
}
}

View 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");
}
}

View 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");
}
}

View 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 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());
}
}

View 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);
}
}

View 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
}
}

View 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;
}
}

View 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
}

View 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; }
}

View 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();
}
}

View 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();
}
}
}

View 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;
}
}

View 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();
}

View 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;
}
}

View 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;
}
}

View 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"));
}
}

View 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();
}
}

View 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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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.");
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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) { }
}
}

View File

@ -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);
}
}
}

View 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();
}
}

View File

@ -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();
}
}