mirror of
https://bitbucket.org/projectswg/lightspeed.git
synced 2026-01-16 23:04:40 -05:00
Added in git status checking for remote updates
This commit is contained in:
@@ -7,5 +7,13 @@
|
||||
<classpathentry kind="lib" path="lib/fast-json-1.4.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="lib" path="/home/josh/Downloads/nanohttpd-nanohttpd-project-2.3.1/core/target/nanohttpd-2.3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/org.eclipse.jgit-4.6.0.201612231935-r.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:platform:/resource/Lightspeed/lib/org.eclipse.jgit-4.6.0.201612231935-r-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="lib/slf4j-nop-1.7.24.jar"/>
|
||||
<classpathentry kind="lib" path="lib/slf4j-api-1.7.24.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jsch-0.1.54.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
BIN
lib/jsch-0.1.54.jar
Normal file
BIN
lib/jsch-0.1.54.jar
Normal file
Binary file not shown.
BIN
lib/org.eclipse.jgit-4.6.0.201612231935-r-javadoc.jar
Normal file
BIN
lib/org.eclipse.jgit-4.6.0.201612231935-r-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/org.eclipse.jgit-4.6.0.201612231935-r.jar
Normal file
BIN
lib/org.eclipse.jgit-4.6.0.201612231935-r.jar
Normal file
Binary file not shown.
BIN
lib/slf4j-api-1.7.24.jar
Normal file
BIN
lib/slf4j-api-1.7.24.jar
Normal file
Binary file not shown.
BIN
lib/slf4j-nop-1.7.24.jar
Normal file
BIN
lib/slf4j-nop-1.7.24.jar
Normal file
Binary file not shown.
@@ -0,0 +1,64 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.concurrency;
|
||||
|
||||
public class PswgBasicScheduledThread extends PswgScheduledThreadPool {
|
||||
|
||||
private final Runnable runnable;
|
||||
|
||||
public PswgBasicScheduledThread(String name, Runnable runnable) {
|
||||
super(1, name);
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
throw new UnsupportedOperationException("Cannot use this function. Must use startX(initialDelay, periodicDelay)");
|
||||
}
|
||||
|
||||
public void startWithFixedRate(long initialDelay, long periodicDelay) {
|
||||
super.start();
|
||||
super.executeWithFixedRate(initialDelay, periodicDelay, runnable);
|
||||
}
|
||||
|
||||
public void startWithFixedDelay(long initialDelay, long periodicDelay) {
|
||||
super.start();
|
||||
super.executeWithFixedDelay(initialDelay, periodicDelay, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeWithFixedRate(long initialDelay, long periodicDelay, Runnable runnable) {
|
||||
throw new UnsupportedOperationException("Runnable is defined in the constructor!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeWithFixedDelay(long initialDelay, long periodicDelay, Runnable runnable) {
|
||||
throw new UnsupportedOperationException("Runnable is defined in the constructor!");
|
||||
}
|
||||
|
||||
}
|
||||
65
src/com/projectswg/common/concurrency/PswgBasicThread.java
Normal file
65
src/com/projectswg/common/concurrency/PswgBasicThread.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.concurrency;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class PswgBasicThread extends PswgThreadPool {
|
||||
|
||||
private final AtomicBoolean executing;
|
||||
private final Runnable runnable;
|
||||
|
||||
public PswgBasicThread(String name, Runnable runnable) {
|
||||
super(1, name);
|
||||
this.executing = new AtomicBoolean(false);
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
super.execute(() -> {
|
||||
executing.set(true);
|
||||
try {
|
||||
runnable.run();
|
||||
} finally {
|
||||
executing.set(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isExecuting() {
|
||||
return executing.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
throw new UnsupportedOperationException("Runnable is defined in the constructor!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.concurrency;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.projectswg.common.control.Assert;
|
||||
|
||||
public class PswgScheduledThreadPool {
|
||||
|
||||
private final AtomicBoolean running;
|
||||
private final int nThreads;
|
||||
private final ThreadFactory threadFactory;
|
||||
private ScheduledExecutorService executor;
|
||||
|
||||
public PswgScheduledThreadPool(int nThreads, String nameFormat) {
|
||||
this.running = new AtomicBoolean(false);
|
||||
this.nThreads = nThreads;
|
||||
this.threadFactory = new CustomThreadFactory(nameFormat);
|
||||
this.executor = null;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Assert.test(!running.getAndSet(true));
|
||||
executor = Executors.newScheduledThreadPool(nThreads, threadFactory);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
Assert.test(running.getAndSet(false));
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
public void executeWithFixedRate(long initialDelay, long time, Runnable runnable) {
|
||||
Assert.test(running.get());
|
||||
executor.scheduleAtFixedRate(() -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}, initialDelay, time, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void executeWithFixedDelay(long initialDelay, long time, Runnable runnable) {
|
||||
Assert.test(running.get());
|
||||
executor.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}, initialDelay, time, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public boolean awaitTermination(long time) {
|
||||
Assert.notNull(executor);
|
||||
try {
|
||||
return executor.awaitTermination(time, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CustomThreadFactory implements ThreadFactory {
|
||||
|
||||
private final String pattern;
|
||||
private int counter;
|
||||
|
||||
public CustomThreadFactory(String pattern) {
|
||||
this.pattern = pattern;
|
||||
this.counter = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
String name;
|
||||
if (pattern.contains("%d"))
|
||||
name = String.format(pattern, counter++);
|
||||
else
|
||||
name = pattern;
|
||||
return new Thread(r, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.concurrency;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
|
||||
public class PswgTaskThreadPool<T> extends PswgThreadPool {
|
||||
|
||||
private final Queue<T> tasks;
|
||||
private final Runnable runner;
|
||||
|
||||
public PswgTaskThreadPool(int nThreads, String namePattern, TaskExecutor<T> executor) {
|
||||
super(nThreads, namePattern);
|
||||
this.tasks = new ArrayDeque<>();
|
||||
this.runner = () -> {
|
||||
T t = null;
|
||||
synchronized (tasks) {
|
||||
t = tasks.poll();
|
||||
}
|
||||
if (t != null)
|
||||
executor.run(t);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable runnable) {
|
||||
throw new UnsupportedOperationException("Runnable are posted automatically by addTask!");
|
||||
}
|
||||
|
||||
public void addTask(T t) {
|
||||
synchronized (tasks) {
|
||||
tasks.add(t);
|
||||
}
|
||||
super.execute(runner);
|
||||
}
|
||||
|
||||
public interface TaskExecutor<T> {
|
||||
void run(T t);
|
||||
}
|
||||
|
||||
}
|
||||
108
src/com/projectswg/common/concurrency/PswgThreadPool.java
Normal file
108
src/com/projectswg/common/concurrency/PswgThreadPool.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.concurrency;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.projectswg.common.control.Assert;
|
||||
|
||||
public class PswgThreadPool {
|
||||
|
||||
private final AtomicBoolean running;
|
||||
private final int nThreads;
|
||||
private final ThreadFactory threadFactory;
|
||||
private ExecutorService executor;
|
||||
|
||||
public PswgThreadPool(int nThreads, String nameFormat) {
|
||||
this.running = new AtomicBoolean(false);
|
||||
this.nThreads = nThreads;
|
||||
this.threadFactory = new CustomThreadFactory(nameFormat);
|
||||
this.executor = null;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Assert.test(!running.getAndSet(true));
|
||||
executor = Executors.newFixedThreadPool(nThreads, threadFactory);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
Assert.test(running.getAndSet(false));
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
public void execute(Runnable runnable) {
|
||||
Assert.test(running.get());
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean awaitTermination(long time) {
|
||||
Assert.notNull(executor);
|
||||
try {
|
||||
return executor.awaitTermination(time, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running.get();
|
||||
}
|
||||
|
||||
private static class CustomThreadFactory implements ThreadFactory {
|
||||
|
||||
private final String pattern;
|
||||
private int counter;
|
||||
|
||||
public CustomThreadFactory(String pattern) {
|
||||
this.pattern = pattern;
|
||||
this.counter = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
String name;
|
||||
if (pattern.contains("%d"))
|
||||
name = String.format(pattern, counter++);
|
||||
else
|
||||
name = pattern;
|
||||
return new Thread(r, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
129
src/com/projectswg/common/concurrency/SmartLock.java
Normal file
129
src/com/projectswg/common/concurrency/SmartLock.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.concurrency;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class SmartLock {
|
||||
|
||||
private final Lock lock;
|
||||
private final Condition condition;
|
||||
|
||||
public SmartLock() {
|
||||
this.lock = new ReentrantLock(true);
|
||||
this.condition = lock.newCondition();
|
||||
}
|
||||
|
||||
public void lock() {
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
public void lockInterruptibly() throws InterruptedException {
|
||||
lock.lockInterruptibly();
|
||||
}
|
||||
|
||||
public boolean tryLock() {
|
||||
return lock.tryLock();
|
||||
}
|
||||
|
||||
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
|
||||
return lock.tryLock(time, unit);
|
||||
}
|
||||
|
||||
public void unlock() {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void await() throws InterruptedException {
|
||||
lock();
|
||||
try {
|
||||
condition.await();
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void awaitUninterruptibly() {
|
||||
lock();
|
||||
try {
|
||||
condition.awaitUninterruptibly();
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public long awaitNanos(long nanosTimeout) throws InterruptedException {
|
||||
lock();
|
||||
try {
|
||||
return condition.awaitNanos(nanosTimeout);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean await(long time, TimeUnit unit) throws InterruptedException {
|
||||
lock();
|
||||
try {
|
||||
return condition.await(time, unit);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean awaitUntil(Date deadline) throws InterruptedException {
|
||||
lock();
|
||||
try {
|
||||
return condition.awaitUntil(deadline);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void signal() {
|
||||
lock();
|
||||
try {
|
||||
condition.signal();
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void signalAll() {
|
||||
lock();
|
||||
try {
|
||||
condition.signalAll();
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
151
src/com/projectswg/common/concurrency/SynchronizedQueue.java
Normal file
151
src/com/projectswg/common/concurrency/SynchronizedQueue.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* -------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.common.concurrency;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Queue;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SynchronizedQueue<T> implements Queue<T> {
|
||||
|
||||
private final Queue<T> queue;
|
||||
|
||||
public SynchronizedQueue() {
|
||||
this(new ArrayDeque<>());
|
||||
}
|
||||
|
||||
public SynchronizedQueue(Queue<T> queue) {
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
public synchronized void forEach(Consumer<? super T> action) {
|
||||
queue.forEach(action);
|
||||
}
|
||||
|
||||
public synchronized boolean add(T e) {
|
||||
return queue.add(e);
|
||||
}
|
||||
|
||||
public synchronized boolean offer(T e) {
|
||||
return queue.offer(e);
|
||||
}
|
||||
|
||||
public synchronized int size() {
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
public synchronized boolean isEmpty() {
|
||||
return queue.isEmpty();
|
||||
}
|
||||
|
||||
public synchronized boolean contains(Object o) {
|
||||
return queue.contains(o);
|
||||
}
|
||||
|
||||
public synchronized T remove() {
|
||||
return queue.remove();
|
||||
}
|
||||
|
||||
public synchronized T poll() {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
public synchronized T element() {
|
||||
return queue.element();
|
||||
}
|
||||
|
||||
public synchronized Iterator<T> iterator() {
|
||||
return queue.iterator();
|
||||
}
|
||||
|
||||
public synchronized T peek() {
|
||||
return queue.peek();
|
||||
}
|
||||
|
||||
public synchronized Object[] toArray() {
|
||||
return queue.toArray();
|
||||
}
|
||||
|
||||
public synchronized <E> E[] toArray(E[] a) {
|
||||
return queue.toArray(a);
|
||||
}
|
||||
|
||||
public synchronized boolean remove(Object o) {
|
||||
return queue.remove(o);
|
||||
}
|
||||
|
||||
public synchronized boolean containsAll(Collection<?> c) {
|
||||
return queue.containsAll(c);
|
||||
}
|
||||
|
||||
public synchronized boolean addAll(Collection<? extends T> c) {
|
||||
return queue.addAll(c);
|
||||
}
|
||||
|
||||
public synchronized boolean removeAll(Collection<?> c) {
|
||||
return queue.removeAll(c);
|
||||
}
|
||||
|
||||
public synchronized boolean removeIf(Predicate<? super T> filter) {
|
||||
return queue.removeIf(filter);
|
||||
}
|
||||
|
||||
public synchronized boolean retainAll(Collection<?> c) {
|
||||
return queue.retainAll(c);
|
||||
}
|
||||
|
||||
public synchronized void clear() {
|
||||
queue.clear();
|
||||
}
|
||||
|
||||
public synchronized boolean equals(Object o) {
|
||||
return queue.equals(o);
|
||||
}
|
||||
|
||||
public synchronized int hashCode() {
|
||||
return queue.hashCode();
|
||||
}
|
||||
|
||||
public synchronized Spliterator<T> spliterator() {
|
||||
return queue.spliterator();
|
||||
}
|
||||
|
||||
public synchronized Stream<T> stream() {
|
||||
return queue.stream();
|
||||
}
|
||||
|
||||
public synchronized Stream<T> parallelStream() {
|
||||
return queue.parallelStream();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,21 +33,31 @@ import com.projectswg.lightspeed.build.ServerBuildData;
|
||||
public class LaunchStarshipIntent extends Intent {
|
||||
|
||||
private ServerBuildData build;
|
||||
private boolean redeploy;
|
||||
|
||||
public LaunchStarshipIntent() {
|
||||
this(null);
|
||||
this(null, false);
|
||||
}
|
||||
|
||||
public LaunchStarshipIntent(ServerBuildData build) {
|
||||
public LaunchStarshipIntent(ServerBuildData build, boolean redeploy) {
|
||||
setBuild(build);
|
||||
setRedeploy(redeploy);
|
||||
}
|
||||
|
||||
public ServerBuildData getBuild() {
|
||||
return build;
|
||||
}
|
||||
|
||||
public boolean isRedeploy() {
|
||||
return redeploy;
|
||||
}
|
||||
|
||||
public void setBuild(ServerBuildData build) {
|
||||
this.build = build;
|
||||
}
|
||||
|
||||
public void setRedeploy(boolean redeploy) {
|
||||
this.redeploy = redeploy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,21 +33,31 @@ import com.projectswg.lightspeed.server.ServerServerData;
|
||||
public class PrepareStarshipIntent extends Intent {
|
||||
|
||||
private ServerServerData server;
|
||||
private boolean redeploy;
|
||||
|
||||
public PrepareStarshipIntent() {
|
||||
this(null);
|
||||
this(null, false);
|
||||
}
|
||||
|
||||
public PrepareStarshipIntent(ServerServerData server) {
|
||||
public PrepareStarshipIntent(ServerServerData server, boolean redeploy) {
|
||||
setServer(server);
|
||||
setRedeploy(redeploy);
|
||||
}
|
||||
|
||||
public ServerServerData getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public boolean isRedeploy() {
|
||||
return redeploy;
|
||||
}
|
||||
|
||||
public void setServer(ServerServerData server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public void setRedeploy(boolean redeploy) {
|
||||
this.redeploy = redeploy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,9 +110,8 @@ public class DeploymentService extends Service {
|
||||
|
||||
private void handleLaunchStarshipIntent(LaunchStarshipIntent lsi) {
|
||||
ServerBuildData build = lsi.getBuild();
|
||||
Log.i("Deploying %s", build.getServer().getName());
|
||||
ServerDeploymentData deployment = new ServerDeploymentData(deploymentId.incrementAndGet(), build);
|
||||
launch(deployment);
|
||||
launch(deployment, lsi.isRedeploy());
|
||||
}
|
||||
|
||||
private File getJdk() {
|
||||
@@ -178,7 +177,7 @@ public class DeploymentService extends Service {
|
||||
ServerBuildData build = server.getLastBuild();
|
||||
if (!launchStarshipChecks(build))
|
||||
return;
|
||||
new LaunchStarshipIntent(build).broadcast();
|
||||
new LaunchStarshipIntent(build, false).broadcast();
|
||||
}
|
||||
|
||||
private boolean launchStarshipChecks(ServerBuildData build) {
|
||||
@@ -197,10 +196,10 @@ public class DeploymentService extends Service {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void launch(ServerDeploymentData deployment) {
|
||||
private void launch(ServerDeploymentData deployment, boolean redeploy) {
|
||||
Assert.notNull(deployment.getServer());
|
||||
String serverId = deployment.getServer().getName();
|
||||
if (isDeploying(serverId)) {
|
||||
if (isDeploying(serverId) && !redeploy) {
|
||||
Log.e("Unable to deploy %s. Already deploying!", serverId);
|
||||
return;
|
||||
}
|
||||
@@ -208,14 +207,20 @@ public class DeploymentService extends Service {
|
||||
synchronized (deployments) {
|
||||
ServerDeploymentData old = deployments.put(serverId, deployment);
|
||||
if (old != null && old.isAlive()) {
|
||||
Log.e("Unable to deploy %s. Already deploying!", serverId);
|
||||
deployments.put(serverId, old);
|
||||
return;
|
||||
if (!redeploy) {
|
||||
Log.e("Unable to deploy %s. Already deploying!", serverId);
|
||||
deployments.put(serverId, old);
|
||||
return;
|
||||
} else {
|
||||
Log.i("Shutting down old deployment of %s", serverId);
|
||||
old.getProcess().stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized (deploymentHistory) {
|
||||
deploymentHistory.add(deployment);
|
||||
}
|
||||
Log.i("Deploying %s", serverId);
|
||||
launchProcess(deployment);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ public class BuildService extends Service {
|
||||
Log.i("Building %s...", psi.getServer().getName());
|
||||
ServerBuildData installation = buildMethod.createJar(buildId.incrementAndGet(), psi.getServer(), new InstallationCallback() {
|
||||
public void onStateChanged(ServerBuildData build, InstallationState oldState, InstallationState newState) { }
|
||||
public void onCompleted(ServerBuildData build) { BuildService.this.onCompleted(psi.getServer().getName(), build); }
|
||||
public void onCompleted(ServerBuildData build) { BuildService.this.onCompleted(psi.getServer().getName(), build, psi.isRedeploy()); }
|
||||
public void onCancelled(ServerBuildData build) { BuildService.this.onCancelled(psi.getServer().getName(), build); }
|
||||
});
|
||||
synchronized (inprogress) {
|
||||
@@ -135,7 +135,7 @@ public class BuildService extends Service {
|
||||
PostBuildPacket p = new PostBuildPacket(params);
|
||||
ServerServerData server = getBackendData().getServer(p.getServerId());
|
||||
if (server != null)
|
||||
new PrepareStarshipIntent(server).broadcast();
|
||||
new PrepareStarshipIntent(server, false).broadcast();
|
||||
return new PostResult(server != null).getJSON();
|
||||
}
|
||||
|
||||
@@ -174,11 +174,11 @@ public class BuildService extends Service {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void onCompleted(String serverId, ServerBuildData build) {
|
||||
private void onCompleted(String serverId, ServerBuildData build, boolean redeploy) {
|
||||
synchronized (inprogress) {
|
||||
Assert.notNull(inprogress.remove(serverId));
|
||||
}
|
||||
processBuildCompleted(buildId.incrementAndGet(), serverId, build);
|
||||
processBuildCompleted(buildId.incrementAndGet(), serverId, build, redeploy);
|
||||
}
|
||||
|
||||
private void onCancelled(String serverId, ServerBuildData build) {
|
||||
@@ -196,7 +196,7 @@ public class BuildService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private void processBuildCompleted(long id, String serverId, ServerBuildData build) {
|
||||
private void processBuildCompleted(long id, String serverId, ServerBuildData build, boolean redeploy) {
|
||||
ServerServerData server = getBackendData().getServer(serverId);
|
||||
if (server == null) {
|
||||
Log.e("Build Success - error while retrieving server information. Server: %s", serverId);
|
||||
@@ -211,13 +211,13 @@ public class BuildService extends Service {
|
||||
}
|
||||
}
|
||||
getBackendData().insertBuild(build);
|
||||
processPostBuild(build);
|
||||
processPostBuild(build, redeploy);
|
||||
}
|
||||
|
||||
private void processPostBuild(ServerBuildData build) {
|
||||
private void processPostBuild(ServerBuildData build, boolean redeploy) {
|
||||
if (build.isBuildSuccess() && build.isTestSuccess()) {
|
||||
Log.i("Build Success! Server: %s", build.getServer().getName());
|
||||
new LaunchStarshipIntent(build).broadcast();
|
||||
new LaunchStarshipIntent(build, redeploy).broadcast();
|
||||
} else if (build.isBuildSuccess()) {
|
||||
Log.e("Tests Failed! Server: %s", build.getServer().getName());
|
||||
Log.e("Output:%n%s", build.getTestString());
|
||||
|
||||
@@ -27,10 +27,79 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.lightspeed.git;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.PullResult;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.ProgressMonitor;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
||||
|
||||
import com.projectswg.common.info.Log;
|
||||
|
||||
public class GitInterface {
|
||||
|
||||
public GitInterface() {
|
||||
|
||||
}
|
||||
|
||||
public String getLastCommit(String repository) throws IOException {
|
||||
try (Git git = new Git(FileRepositoryBuilder.create(new File(repository, ".git")))) {
|
||||
Map<String, Ref> remoteRefs = git.lsRemote().setRemote("origin").setTags(false).setHeads(true).callAsMap();
|
||||
Ref qa = remoteRefs.get("refs/heads/quality_assurance");
|
||||
if (qa == null)
|
||||
return "";
|
||||
return qa.getObjectId().getName();
|
||||
} catch (GitAPIException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean pullLastUpdate(String repository) throws IOException {
|
||||
try (Git git = new Git(FileRepositoryBuilder.create(new File(repository, ".git")))) {
|
||||
PullResult res = git.pull()
|
||||
.setRemote("origin")
|
||||
.setRemoteBranchName("quality_assurance")
|
||||
.setRebase(true)
|
||||
.setProgressMonitor(new CustomProgressMonitor()).call();
|
||||
return res.isSuccessful();
|
||||
} catch (GitAPIException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private class CustomProgressMonitor implements ProgressMonitor {
|
||||
|
||||
private final AtomicInteger tasks = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void beginTask(String title, int totalWork) {
|
||||
tasks.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTask() {
|
||||
tasks.decrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(int totalTasks) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int completed) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,10 @@ public class ServerServerData {
|
||||
return shared.getJvmArguments();
|
||||
}
|
||||
|
||||
public String getLastCommit() {
|
||||
return shared.getLastCommit();
|
||||
}
|
||||
|
||||
public void setDirectory(String directory) {
|
||||
shared.setDirectory(directory);
|
||||
}
|
||||
@@ -68,6 +72,10 @@ public class ServerServerData {
|
||||
public void setJvmArguments(String jvmArgs) {
|
||||
shared.setJvmArguments(jvmArgs);
|
||||
}
|
||||
|
||||
public void setLastCommit(String lastCommit) {
|
||||
shared.setLastCommit(lastCommit);
|
||||
}
|
||||
|
||||
public void addBuild(ServerBuildData build) {
|
||||
shared.addBuild(build.getShared());
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.lightspeed.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -34,30 +35,65 @@ import java.util.Set;
|
||||
|
||||
import me.joshlarson.json.JSONObject;
|
||||
|
||||
import com.projectswg.common.concurrency.PswgBasicScheduledThread;
|
||||
import com.projectswg.common.control.Service;
|
||||
import com.projectswg.common.info.Log;
|
||||
import com.projectswg.common.intents.PrepareStarshipIntent;
|
||||
import com.projectswg.common.intents.RegisterHttpListenerIntent;
|
||||
import com.projectswg.common.network.packets.PacketType;
|
||||
import com.projectswg.common.network.packets.request.RequestServerDetailedPacket;
|
||||
import com.projectswg.common.network.packets.response.ResponseServerDetailedPacket;
|
||||
import com.projectswg.common.network.packets.response.ResponseServerListPacket;
|
||||
import com.projectswg.lightspeed.git.GitInterface;
|
||||
import com.projectswg.lightspeed_frontend.data.SharedServerData;
|
||||
|
||||
public class ServerService extends Service {
|
||||
|
||||
private final Set<ServerServerData> servers;
|
||||
private final PswgBasicScheduledThread gitScanner;
|
||||
private final GitInterface git;
|
||||
|
||||
public ServerService() {
|
||||
this.servers = new HashSet<>();
|
||||
this.gitScanner = new PswgBasicScheduledThread("git-scanner", () -> scanServersForUpdates());
|
||||
this.git = new GitInterface();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
servers.addAll(getBackendData().getServerList());
|
||||
gitScanner.startWithFixedDelay(0, 15000);
|
||||
new RegisterHttpListenerIntent(PacketType.REQUEST_SERVER_LIST, (type, params) -> onRequestServerList(params)).broadcast();
|
||||
new RegisterHttpListenerIntent(PacketType.REQUEST_SERVER_DETAILED, (type, params) -> onRequestServerDetailed(params)).broadcast();
|
||||
return super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean terminate() {
|
||||
gitScanner.stop();
|
||||
return super.terminate();
|
||||
}
|
||||
|
||||
private void scanServersForUpdates() {
|
||||
for (ServerServerData server : servers) {
|
||||
try {
|
||||
String commit = git.getLastCommit(server.getDirectory());
|
||||
String lastCommit = server.getLastCommit();
|
||||
if (!lastCommit.equals(commit)) {
|
||||
if (!git.pullLastUpdate(server.getDirectory())) {
|
||||
Log.e("Failed to pull latest update from %s", server.getName());
|
||||
continue;
|
||||
}
|
||||
server.setLastCommit(commit);
|
||||
Log.i("Server %s was updated. Rebuilding...", server.getName());
|
||||
new PrepareStarshipIntent(server, true).broadcast();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JSONObject onRequestServerList(JSONObject params) {
|
||||
synchronized (servers) {
|
||||
List<SharedServerData> serverList = new ArrayList<>(servers.size());
|
||||
|
||||
@@ -44,6 +44,7 @@ public class SharedServerData {
|
||||
private final TreeMap<Long, SharedDeploymentData> deployments;
|
||||
private String directory;
|
||||
private String jvmArgs;
|
||||
private String lastCommit;
|
||||
|
||||
public SharedServerData(String name) {
|
||||
this.name = name;
|
||||
@@ -51,6 +52,7 @@ public class SharedServerData {
|
||||
this.deployments = new TreeMap<>();
|
||||
this.directory = "";
|
||||
this.jvmArgs = "";
|
||||
this.lastCommit = "";
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -65,6 +67,10 @@ public class SharedServerData {
|
||||
return jvmArgs;
|
||||
}
|
||||
|
||||
public String getLastCommit() {
|
||||
return lastCommit;
|
||||
}
|
||||
|
||||
public List<SharedBuildData> getBuilds() {
|
||||
synchronized (builds) {
|
||||
List<SharedBuildData> buildList = new ArrayList<>(builds.values());
|
||||
@@ -191,6 +197,10 @@ public class SharedServerData {
|
||||
this.jvmArgs = jvmArgs;
|
||||
}
|
||||
|
||||
public void setLastCommit(String lastCommit) {
|
||||
this.lastCommit = lastCommit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
|
||||
Reference in New Issue
Block a user