Skip to content

Commit

Permalink
Dunno what I was doing like 15 days ago.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brahvim committed Oct 15, 2024
1 parent 3a4a915 commit b93dd32
Show file tree
Hide file tree
Showing 13 changed files with 1,196 additions and 181 deletions.
46 changes: 37 additions & 9 deletions res/strings/en/agc-string-table.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[WindowTitles]
stageHome=Home - Android Game Controller
stageProfiles=Profiles - Android Game Controller
stageEditor=Editor - Android Game Controller

dialogTray=Tray - Android Game Controller
dialogAbout=About Android Game Controller
Expand All @@ -12,13 +13,11 @@ fileChooserProfileImporter=Import Profile - Android Game Controller

# `Dialog`s:
[DialogAbout]
buttonClose=Close
label0=An app by Brahvim Bhaktvatsal.
label1=Find source code, documentation, and others on GitHub!

buttonClose=Close
urlGitHub=https://github.com/Brahvim/Android-Game-Controller-Server


# `ListView`s:

[ListTrayOptions]
Expand All @@ -34,19 +33,44 @@ waiting=Wait `%d` (`%d`)...

[ListHomeOptions]
label=Options:
ADD=Add a phone.
STOP=Stop adding more phones.
REMOVE=Disconnect selected phones.
ADD=Add a phone!
STOP=Don't allow more phones!
REMOVE=Disconnect selected.
CONTROLS=Show controls for selected.
PROFILES=Open Profile Chooser window.
CONTROLS=Show selected phones' controls.
[ListEditorOptions]
label=Options:
ADD=Add a control.
REMOVE=Remove selected.
[ListEditorControls]
label=Controls:
[ListSelectorControls]
dpadUp=D-Up
dpadDown=D-Down
dpadLeft=D-Left
dpadRight=D-Right
touchpad=Touchpad
thumbstick=Thumbstick
toggleSwitch=Switch Toggle
toggleCircle=Circle Toggle
toggleKeyboard=Keyboard Toggle
toggleRounded=Round Rect Toggle
buttonCircled=Circle Button
buttonRounded=Round Rect Button
[ListProfileChooserOptions]
label=Options:
REMOVE=Delete profile.
HOME=Open Home window.
CREATE=Create a profile.
IMPORT=Import a profile.
REMOVE=Delete a profile.
EXPORT=Export a profile.
IMPORT=Import a profile.
[ListProfileChooserProfiles]
label=Profiles:
Expand All @@ -67,6 +91,10 @@ PROFILES=(Macro: `F` anywhere in this window.)
ADD=(Macro: `Insert` anywhere in this window.)
STOP=(Macro: `Ctrl` + `Shift` + `Delete` anywhere in this window.)
[TooltipsEditorListOptions]
REMOVE=(Macro: `Delete` inside phones list.)
ADD=(Macro: `Insert` anywhere in this window.)
[TooltipsProfileChooserListOptions]
EXPORT=(Macro: `E` in profiles list.)
REMOVE=(Macro: `Delete` in profiles list.)
Expand Down
3 changes: 3 additions & 0 deletions src/com/brahvim/agc/server/ExitCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ public enum ExitCode {
OKAY("User exited app."),
UNKNOWN("Unknown <:(..."),

UDP_SOCKET_CREATION_PERMISSION("UDP socket creation not allowed."),
UDP_SOCKET_ACCEPT_PERMISSION("UDP socket not allowed to accept connections."),

SSL_SOCKET_CREATION_PERMISSION("SSL socket creation not allowed."),
SSL_SOCKET_ACCEPT_PERMISSION("SSL socket not allowed to accept connections."),

Expand Down
182 changes: 103 additions & 79 deletions src/com/brahvim/agc/server/back/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,131 +2,155 @@

import java.net.DatagramSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.IdentityHashMap;

import com.brahvim.agc.server.ExitCode;
import com.brahvim.agc.server.front.App;

// No, I'm not making this `AutoCloseable`! -v-
public final class Client {

// region Fields.
private static final ArrayList<DatagramSocket> LIST_SOCKETS_UDP = new ArrayList<>(1);
private static final ArrayList<Socket> LIST_SOCKETS_SSL = new ArrayList<>(1);
private static final ArrayList<Thread> LIST_THREADS_UDP = new ArrayList<>(1);
private static final ArrayList<DatagramSocket> LIST_SOCKS_UDP = new ArrayList<>(1);
private static final IdentityHashMap<Integer, String> MAP_UI_ENTRY = new IdentityHashMap<>(1);
private static final IdentityHashMap<Integer, Socket> MAP_SOCKS_SSL = new IdentityHashMap<>(1);
private static final ArrayDeque<Integer> QUEUE_FREE_INDICES = new ArrayDeque<>(1);
private static final ArrayList<String> LIST_UI_ENTRIES = new ArrayList<>(1);
private static final ArrayList<Integer> LIST_ACTIVE = new ArrayList<>(1);

private static int count = 1;
// private static final AtomicBoolean inCreateOrDestroy = new AtomicBoolean();
// endregion

private final Integer id;
private static final ArrayDeque<Integer> QUEUE_FREE_SOCKETS_SSL = new ArrayDeque<>(2);
private static final ArrayDeque<Integer> QUEUE_FREE_UI_ENTRIES = new ArrayDeque<>(2);
private static final ArrayDeque<Integer> QUEUE_FREE_CLIENTS = new ArrayDeque<>(2);

static {
// `0` shall be `null`. ...The `null`-object pattern. <Sigh>.
Client.QUEUE_FREE_INDICES.add(1);
private static int countSocketsSsl = 1;
private static int countUiEntries = 1;
private static int countClient = 1;

Client.MAP_UI_ENTRY.put(0, null);
Client.MAP_SOCKS_SSL.put(0, null);
private int idSocketSsl = 0;
private int idUiEntry = 0;
private int idClient = 0;
// endregion

Client.LIST_THREADS_UDP.add(null);
Client.LIST_SOCKS_UDP.add(null);
static {
// `0` shall be `null`. ...The `null`-object pattern! Yay!...
Client.QUEUE_FREE_CLIENTS.add(1);
Client.QUEUE_FREE_UI_ENTRIES.add(1);
Client.QUEUE_FREE_SOCKETS_SSL.add(1);

Client.LIST_UI_ENTRIES.add("");
Client.LIST_SOCKETS_SSL.add(new Socket());

try {
final DatagramSocket closedSocket = new DatagramSocket(0);
closedSocket.close();
Client.LIST_SOCKETS_UDP.add(closedSocket);
} catch (final SocketException e) {
App.exit(ExitCode.UNKNOWN);
}

Client.LIST_THREADS_UDP.add(Thread.currentThread());
}

public Client() {
this.id = Client.create();
}

public synchronized void destroy() {
// synchronized (Client.waitForOtherCreateOrDestroy()) {
// `Map`s:
Client.MAP_UI_ENTRY.remove(this.id);
Client.MAP_SOCKS_SSL.remove(this.id);
// Client.idToSoaIndexMap.remove(index);

// `List`s:
Client.LIST_SOCKS_UDP.set(this.id, null);
Client.LIST_THREADS_UDP.set(this.id, null);

Client.QUEUE_FREE_INDICES.add(this.id);
// Client.endCurrentCreateOrDestroy();
// }
this.idClient = Client.createClient();
Client.LIST_ACTIVE.add(this.idClient);
}

// region Getters.
public static int getCount() {
return Client.count;
public synchronized String getUiEntry() {
return Client.LIST_UI_ENTRIES.get(this.idClient);
}

public String getUiEntry() {
return Client.MAP_UI_ENTRY.get(this.id);
public synchronized Thread getThreadUdp() {
return Client.LIST_THREADS_UDP.get(this.idClient);
}

public Socket getSslSocket() {
return Client.MAP_SOCKS_SSL.get(this.id);
public synchronized Socket getSocketSsl() {
return Client.LIST_SOCKETS_SSL.get(this.idClient);
}

public Thread getUdpSocketThread() {
return Client.LIST_THREADS_UDP.get(this.id);
}

public DatagramSocket getUdpSocket() {
return Client.LIST_SOCKS_UDP.get(this.id);
public synchronized DatagramSocket getSocketUdp() {
return Client.LIST_SOCKETS_UDP.get(this.idClient);
}
// endregion

// region Setters.
public String setUiEntry(final String p_entry) {
return Client.MAP_UI_ENTRY.put(this.id, p_entry);
if (this.idUiEntry == 0)
this.createUiEntry();

return Client.LIST_UI_ENTRIES.set(this.idUiEntry, p_entry);
}

public synchronized Socket setSslSocket(final Socket p_sslSocket) {
return Client.MAP_SOCKS_SSL.put(this.id, p_sslSocket);
public synchronized Thread setThreadUdp(final Thread p_thread) {
return Client.LIST_THREADS_UDP.set(this.idClient, p_thread);
}

public synchronized Thread setUdpSocketThread(final Thread p_thread) {
return Client.LIST_THREADS_UDP.set(this.id, p_thread);
public synchronized Socket setSocketSsl(final Socket p_sslSocket) {
if (this.idSocketSsl == 0)
this.createSocketSsl();

return Client.LIST_SOCKETS_SSL.set(this.idSocketSsl, p_sslSocket);
}

public synchronized DatagramSocket setUdpSocket(final DatagramSocket p_udpSocket) {
return Client.LIST_SOCKS_UDP.set(this.id, p_udpSocket);
public synchronized DatagramSocket setSocketUdp(final DatagramSocket p_udpSocket) {
return Client.LIST_SOCKETS_UDP.set(this.idClient, p_udpSocket);
}
// endregion

// private static AtomicBoolean waitForOtherCreateOrDestroy() {
// synchronized (Client.inCreateOrDestroy) {
// while (Client.inCreateOrDestroy.get())
// try {
// Client.inCreateOrDestroy.wait();
// } catch (final InterruptedException e) {
// Thread.currentThread().interrupt();
// }
// return Client.inCreateOrDestroy;
// }
// }
//
// private static AtomicBoolean endCurrentCreateOrDestroy() {
// synchronized (Client.inCreateOrDestroy) {
// Client.inCreateOrDestroy.set(false);
// Client.inCreateOrDestroy.notifyAll();
// return Client.inCreateOrDestroy;
// }
// }

private static synchronized Integer create() {
// synchronized (Client.waitForOtherCreateOrDestroy()) {
Integer id = Client.QUEUE_FREE_INDICES.poll();
// region Lifecycle.
public synchronized void destroy() {
// Perhaps these may get collected by the GC!...
Client.LIST_SOCKETS_UDP.set(this.idClient, null);
Client.LIST_THREADS_UDP.set(this.idClient, null);

Client.LIST_ACTIVE.remove(this.idClient);

Client.LIST_UI_ENTRIES.set(this.idUiEntry, null);
Client.LIST_SOCKETS_SSL.set(this.idSocketSsl, null);

Client.QUEUE_FREE_CLIENTS.add(this.idClient);
Client.QUEUE_FREE_UI_ENTRIES.add(this.idUiEntry);
Client.QUEUE_FREE_SOCKETS_SSL.add(this.idSocketSsl);

// ...We're `null` now...:
this.idClient = 0;
this.idUiEntry = 0;
this.idSocketSsl = 0;
}

private static synchronized int createClient() {
Integer id = Client.QUEUE_FREE_CLIENTS.poll();

if (id == null)
id = ++Client.count;
id = ++Client.countClient;

// Client.idToSoaIndexMap.put(myId, soaIndex);
App.ensureArrayListSize(Client.LIST_SOCKS_UDP, id);
App.ensureArrayListSize(Client.LIST_SOCKETS_UDP, id);
App.ensureArrayListSize(Client.LIST_THREADS_UDP, id);

return id;
}

private void createSocketSsl() {
Integer id = Client.QUEUE_FREE_SOCKETS_SSL.poll();

if (id == null)
id = ++Client.countSocketsSsl;

App.ensureArrayListSize(Client.LIST_SOCKETS_SSL, id);
this.idSocketSsl = id;
}

private void createUiEntry() {
Integer id = Client.QUEUE_FREE_UI_ENTRIES.poll();

if (id == null)
id = ++Client.countUiEntries;

App.ensureArrayListSize(Client.LIST_UI_ENTRIES, id);
this.idUiEntry = id;
}
// endregion

}
24 changes: 13 additions & 11 deletions src/com/brahvim/agc/server/back/Profile.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
public final class Profile {

// region Fields.
public static final ArrayList<Profile> LIST_ALL = new ArrayList<>(); // NOSONAR, there's a reason why it exists...
protected static final ArrayList<Integer> LIST_ALL = new ArrayList<>();
protected static final ArrayList<Integer> LIST_ACTIVE = new ArrayList<>();

private static final ArrayList<File> LIST_FILES = new ArrayList<>();
private static final ArrayList<String> LIST_DATA = new ArrayList<>();
Expand All @@ -30,8 +31,8 @@ public final class Profile {
}

public Profile(final File p_file) throws IOException {
Profile.LIST_ALL.add(this);
this.id = Profile.create();
Profile.LIST_ALL.add(this.id);

final StringBuilder builder = new StringBuilder();

Expand All @@ -47,32 +48,33 @@ public Profile(final File p_file) throws IOException {
this.setName(String.format("Profile %d", Profile.count));
}

public String getData() {
return Profile.LIST_DATA.get(this.id);
}

public File getFile() {
return Profile.LIST_FILES.get(this.id);
}

public String getName() {
return Profile.LIST_NAMES.get(this.id);
public String getData() {
return Profile.LIST_DATA.get(this.id);
}

public String setData(final String p_data) {
return Profile.LIST_DATA.set(this.id, p_data);
public String getName() {
return Profile.LIST_NAMES.get(this.id);
}

public File setFile(final File p_file) {
return Profile.LIST_FILES.set(this.id, p_file);
}

public String setData(final String p_data) {
return Profile.LIST_DATA.set(this.id, p_data);
}

public String setName(final String p_name) {
return Profile.LIST_NAMES.set(this.id, p_name);
}

public synchronized void destroy() {
Profile.LIST_ALL.remove(this);
Profile.LIST_ALL.remove(this.id);
Profile.LIST_ACTIVE.remove(this.id);
Profile.LIST_DATA.set(this.id, null);

Profile.QUEUE_FREE_INDICES.add(this.id);
Expand Down
Loading

0 comments on commit b93dd32

Please sign in to comment.