hook up core and backend

This commit is contained in:
Zlatin Balevsky
2019-11-11 22:42:55 +00:00
parent 3db167bade
commit 29e499fe9d
12 changed files with 301 additions and 36 deletions

View File

@@ -4,18 +4,24 @@ import griffon.core.artifact.GriffonController
import griffon.core.controller.ControllerAction
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
import groovy.util.logging.Log
import net.i2p.crypto.DSAEngine
import net.i2p.data.DataHelper
import net.i2p.data.Signature
import java.nio.charset.StandardCharsets
import java.util.logging.Level
import javax.annotation.Nonnull
import com.muwire.core.Persona
import com.muwire.core.chat.ChatCommand
import com.muwire.core.chat.ChatAction
import com.muwire.core.chat.ChatConnection
import com.muwire.core.chat.ChatMessageEvent
import com.muwire.core.chat.ChatServer
@Log
@ArtifactProviderFor(GriffonController)
class ChatRoomController {
@MVCMember @Nonnull
@@ -28,25 +34,78 @@ class ChatRoomController {
String words = view.sayField.text
view.sayField.setText(null)
ChatCommand command
try {
command = new ChatCommand(words)
} catch (Exception nope) {
command = new ChatCommand("/SAY $words")
}
long now = System.currentTimeMillis()
UUID uuid = UUID.randomUUID()
String room = model.console ? ChatServer.CONSOLE : model.room
byte [] sig = ChatConnection.sign(uuid, now, room, words, model.core.me, mvcGroup.parentGroup.model.host, model.core.spk)
byte [] sig = ChatConnection.sign(uuid, now, room, command.source, model.core.me, mvcGroup.parentGroup.model.host, model.core.spk)
def event = new ChatMessageEvent(uuid : uuid,
payload : words,
sender : model.core.me,
host : mvcGroup.parentGroup.model.host,
room : room,
chatTime : now,
sig : sig)
payload : command.source,
sender : model.core.me,
host : mvcGroup.parentGroup.model.host,
room : room,
chatTime : now,
sig : sig)
model.core.eventBus.publish(event)
if (command.payload.length() > 0) {
String toShow = DataHelper.formatTime(now) + " <" + model.core.me.getHumanReadableName() + "> "+command.payload
view.roomTextArea.append(toShow)
view.roomTextArea.append('\n')
}
}
void handleChatMessage(ChatMessageEvent e) {
ChatCommand command
try {
command = new ChatCommand(e.payload)
} catch (Exception bad) {
log.log(Level.WARNING,"bad chat command",bad)
return
}
model.core.eventBus.publish(event)
String toShow = DataHelper.formatTime(now) + " <" + model.core.me.getHumanReadableName() + "> "+words
view.roomTextArea.append(toShow)
view.roomTextArea.append('\n')
switch(command.action) {
case ChatAction.SAY : processSay(e, command.payload);break
case ChatAction.JOIN : processJoin(e.timestamp, e.sender); break
case ChatAction.LEAVE : processLeave(e.timestamp, e.sender); break
}
}
private void processSay(ChatMessageEvent e, String text) {
log.info "processing say $text"
String toDisplay = DataHelper.formatTime(e.timestamp) + " <"+e.sender.getHumanReadableName()+"> " + text + "\n"
runInsideUIAsync {
view.roomTextArea.append(toDisplay)
}
}
private void processJoin(long timestamp, Persona p) {
String toDisplay = DataHelper.formatTime(timestamp) + " " + p.getHumanReadableName() + " joined the room\n"
runInsideUIAsync {
view.roomTextArea.append(toDisplay)
}
}
private void processLeave(long timestamp, Persona p) {
String toDisplay = DataHelper.formatTime(timestamp) + " " + p.getHumanReadableName() + " left the room\n"
runInsideUIAsync {
view.roomTextArea.append(toDisplay)
}
}
void handleLeave(Persona p) {
String toDisplay = DataHelper.formatTime(System.currentTimeMillis()) + " " + p.getHumanReadableName() + " disconnected\n"
runInsideUIAsync {
view.roomTextArea.append(toDisplay)
}
}
}

View File

@@ -2,20 +2,83 @@ package com.muwire.gui
import com.muwire.core.Core
import com.muwire.core.Persona
import com.muwire.core.chat.ChatConnectionAttemptStatus
import com.muwire.core.chat.ChatConnectionEvent
import com.muwire.core.chat.ChatLink
import com.muwire.core.chat.ChatMessageEvent
import com.muwire.core.chat.UIConnectChatEvent
import griffon.core.artifact.GriffonModel
import griffon.transform.Observable
import groovy.util.logging.Log
import griffon.metadata.ArtifactProviderFor
@Log
@ArtifactProviderFor(GriffonModel)
class ChatServerModel {
Persona host
Core core
@Observable boolean disconnectActionEnabled
@Observable ChatConnectionAttemptStatus status
volatile ChatLink link
volatile Thread poller
volatile boolean running
void mvcGroupInit(Map<String, String> params) {
disconnectActionEnabled = host != core.me // can't disconnect from myself
core.eventBus.with {
register(ChatConnectionEvent.class, this)
publish(new UIConnectChatEvent(host : host))
}
running = true
poller = new Thread({eventLoop()} as Runnable)
poller.setDaemon(true)
poller.start()
}
void mvcGroupDestroy() {
running = false
poller?.interrupt()
}
void onChatConnectionEvent(ChatConnectionEvent e) {
if (e.connection != null)
link = e.connection
runInsideUIAsync {
status = e.status
}
}
private void eventLoop() {
while(running) {
ChatLink link = this.link
if (link == null || !link.isUp()) {
Thread.sleep(100)
continue
}
Object event = link.nextEvent()
if (event instanceof ChatMessageEvent)
handleChatMessage(event)
else if (event instanceof Persona)
handleLeave(event)
else
throw new IllegalArgumentException("event type $event")
}
}
private void handleChatMessage(ChatMessageEvent e) {
log.info("dispatching to room ${e.room}")
mvcGroup.childrenGroups[e.room]?.controller?.handleChatMessage(e)
}
private void handleLeave(Persona p) {
mvcGroup.childrenGroups.each {
it.controller.handleLeave(p)
}
}
}

View File

@@ -5,6 +5,8 @@ import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
import javax.swing.SwingConstants
import com.muwire.core.chat.ChatServer
import java.awt.BorderLayout
import javax.annotation.Nonnull
@@ -24,7 +26,10 @@ class ChatServerView {
borderLayout()
tabbedPane(id : model.host.getHumanReadableName()+"-chat-rooms", constraints : BorderLayout.CENTER)
panel(constraints : BorderLayout.SOUTH) {
gridLayout(rows : 1, cols : 3)
panel {}
button(text : "Disconnect", enabled : bind {model.disconnectActionEnabled}, disconnectAction)
label(text : bind {model.status.toString()})
}
}
}
@@ -55,7 +60,7 @@ class ChatServerView {
params['tabName'] = model.host.getHumanReadableName() + "-chat-rooms"
params['room'] = 'Console'
params['console'] = true
mvcGroup.createMVCGroup("chat-room","Console", params)
mvcGroup.createMVCGroup("chat-room",ChatServer.CONSOLE, params)
}
def closeTab = {