Moved everything (except ocelot.jar) to AppData/home

This commit is contained in:
Igor Timofeev 2023-10-16 10:34:58 +00:00
parent d107ce1d82
commit dc253bc85c
15 changed files with 199 additions and 105 deletions

@ -1 +1 @@
Subproject commit a507175686c3a60f61efde013d0269c596e03b28
Subproject commit 525539880fd9510b5a5e476a951d3661a0f5bfa2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="MyFile" fileName="ocelot-desktop.log" immediateFlush="false" append="false">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
<AppenderRef ref="MyFile"/>
</Root>
<Logger name="com.github.sarxos.webcam" level="info"/>
</Loggers>
</Configuration>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

@ -5,8 +5,8 @@ ocelot {
brain {
# This is the path to OpenComputers configuration file, that Ocelot Brain can use
# to apply the settings which can be applicable in emulation context (like `bufferChanges: false`).
# Optional.
configPath: brain.conf
# Optional. By default it's being stored at ~/AppData/Ocelot or ~/.config/ocelot
customConfigPath: null
}
sound {

View File

@ -7,10 +7,10 @@ import ocelot.desktop.ui.swing.SplashScreen
import ocelot.desktop.ui.widget._
import ocelot.desktop.ui.widget.modal.notification.{NotificationDialog, NotificationType}
import ocelot.desktop.util.CommandLine.Argument
import ocelot.desktop.util.FileUtils.getOcelotConfigDirectory
import ocelot.desktop.util._
import org.apache.commons.io.FileUtils
import org.apache.logging.log4j.LogManager
import org.apache.commons.lang3.SystemUtils
import org.lwjgl.opengl.Display
import totoro.ocelot.brain.Ocelot
import totoro.ocelot.brain.nbt.ExtendedNBT.{extendNBTTagCompound, extendNBTTagList}
import totoro.ocelot.brain.nbt.{CompressedStreamTools, NBT, NBTTagCompound, NBTTagString}
@ -29,7 +29,11 @@ import scala.io.Source
import scala.jdk.CollectionConverters._
import scala.util.{Failure, Success, Try, Using}
object OcelotDesktop extends Logging {
object OcelotDesktop
// This configures Log4j appenders & loggers, it should come before Logging in inheritance hierarchy
extends LoggingConfiguration
with Logging
{
System.setProperty("awt.useSystemAAFontSettings", "on")
System.setProperty("swing.aatext", "true")
@ -64,18 +68,46 @@ object OcelotDesktop extends Logging {
splashScreen.setStatus("Loading configuration...", 0.10f)
val customConfigPath = args.get(CommandLine.ConfigPath).flatten
val settingsFile = if (customConfigPath.isEmpty)
getOcelotConfigDirectory.resolve("ocelot.conf")
else
Paths.get(customConfigPath.get)
val desktopConfigPath: Path =
if (customConfigPath.isDefined) {
Paths.get(customConfigPath.get)
}
else {
// TODO: migration for old locations of ocelot.conf, can be safely removed later
// TODO: uncomment this line and delete everything below it when you're ready!
// OcelotPaths.desktopConfig
val newConfigPath = OcelotPaths.desktopConfig
try {
if (!Files.exists(newConfigPath)) {
val oldConfigPath =
if (SystemUtils.IS_OS_WINDOWS)
Paths.get(OcelotPaths.windowsAppDataDirectoryName, "Ocelot", "ocelot.conf")
else
Paths.get(OcelotPaths.linuxHomeDirectoryName, ".config", "ocelot", "ocelot.conf")
if (Files.exists(oldConfigPath))
Files.move(oldConfigPath, newConfigPath)
}
}
catch {
case _: Throwable =>
}
// TODO: end of upper todo <3
newConfigPath
}
Settings.load(desktopConfigPath)
Settings.load(settingsFile)
Messages.load(Source.fromURL(getClass.getResource("/ocelot/desktop/messages.txt")))
ColorScheme.load(Source.fromURL(getClass.getResource("/ocelot/desktop/colorscheme.txt")))
splashScreen.setStatus("Initializing brain...", 0.20f)
Ocelot.configPath = Settings.get.brainConfigPath
Ocelot.initialize(LogManager.getLogger(Ocelot))
Ocelot.configPath = Settings.get.brainCustomConfigPath.map(Paths.get(_))
Ocelot.librariesPath = Some(OcelotPaths.libraries)
Ocelot.initialize(logger)
Items.init()
@ -90,6 +122,8 @@ object OcelotDesktop extends Logging {
val loadRecentWorkspace = Settings.get.recentWorkspace.isDefined && Settings.get.openLastWorkspace
root = new RootWidget(!loadRecentWorkspace)
root.width = Display.getWidth
root.height = Display.getHeight
UiHandler.setRoot(root)
splashScreen.setStatus("Loading workspace...", 0.90f)
@ -151,7 +185,7 @@ object OcelotDesktop extends Logging {
}
WebcamCapture.cleanup()
Settings.save(settingsFile)
Settings.save(desktopConfigPath)
UiHandler.terminate()
ResourceManager.checkEmpty()
@ -237,9 +271,11 @@ object OcelotDesktop extends Logging {
for (path <- oldFiles) {
val oldFile = oldPath.resolve(path.getFileName).toFile
val newFile = outputPath.resolve(path.getFileName).toFile
if (Files.isDirectory(path)) {
FileUtils.copyDirectory(oldFile, newFile)
} else {
}
else {
FileUtils.copyFile(oldFile, newFile)
}
}
@ -290,6 +326,7 @@ object OcelotDesktop extends Logging {
def load(dir: File): Try[Unit] = {
val path = Paths.get(dir.getCanonicalPath, "workspace.nbt")
if (Files.exists(path)) {
Using(new DataInputStream(Files.newInputStream(path))) { reader =>
val nbt = CompressedStreamTools.readCompressed(reader)

View File

@ -14,7 +14,7 @@ import scala.io.{Codec, Source}
class Settings(val config: Config) extends SettingsData {
// TODO: refactor this mess (having to declare every field 3 times is extremely error-prone)
brainConfigPath = config.getOptionalString("ocelot.brain.configPath")
brainCustomConfigPath = config.getOptionalString("ocelot.brain.customConfigPath")
volumeMaster = (config.getDouble("ocelot.sound.volumeMaster") max 0 min 1).toFloat
volumeBeep = (config.getDouble("ocelot.sound.volumeBeep") max 0 min 1).toFloat
@ -114,40 +114,46 @@ object Settings extends Logging {
def load(path: Path): Unit = {
import java.lang.System.{lineSeparator => EOL}
if (Files.exists(path)) {
var stream: InputStream = null
try {
stream = Files.newInputStream(path)
val source = Source.fromInputStream(stream)(Codec.UTF8)
val plain = source.getLines().mkString("", EOL, EOL)
val config = ConfigFactory.parseString(plain)
settings = new Settings(config)
source.close()
logger.info(s"Loaded Ocelot Desktop configuration from: $path")
return
}
catch {
case _: Throwable =>
logger.info(s"Failed to parse $path, using default Ocelot Desktop configuration.")
}
finally {
if (stream != null)
stream.close()
}
}
val defaults = {
val in = getClass.getResourceAsStream("/ocelot/desktop/ocelot.conf")
val config = Source.fromInputStream(in)(Codec.UTF8).getLines().mkString("", EOL, EOL)
in.close()
ConfigFactory.parseString(config)
}
var stream: InputStream = null
try {
stream = Files.newInputStream(path)
val source = Source.fromInputStream(stream)(Codec.UTF8)
val plain = source.getLines().mkString("", EOL, EOL)
val config = ConfigFactory.parseString(plain)
settings = new Settings(config)
source.close()
logger.info(s"Loaded Ocelot Desktop configuration from: $path")
}
catch {
case e: Throwable =>
logger.info("Using default Ocelot Desktop configuration.")
if (Files.exists(path)) {
logger.warn(s"(Failed to parse $path!)", e)
}
settings = new Settings(defaults)
}
finally {
if (stream != null)
stream.close()
}
settings = new Settings(defaults)
}
def save(path: Path): Unit = {
if (settings != null) {
val updatedConfig = settings.config
.withValuePreserveOrigin("ocelot.brain.configPath", settings.brainConfigPath)
.withValuePreserveOrigin("ocelot.brain.customConfigPath", settings.brainCustomConfigPath)
.withValuePreserveOrigin("ocelot.sound.volumeMaster", settings.volumeMaster)
.withValuePreserveOrigin("ocelot.sound.volumeBeep", settings.volumeBeep)
.withValuePreserveOrigin("ocelot.sound.volumeEnvironment", settings.volumeEnvironment)

View File

@ -14,12 +14,10 @@ import scala.collection.mutable
import scala.util.control.Breaks._
//noinspection ScalaWeakerAccess,ScalaUnusedSymbol
class Graphics(private var scalingFactor: Float) extends Logging with Resource {
class Graphics(private var width: Int, private var height: Int, private var scalingFactor: Float) extends Logging with Resource {
private var time = 0f
private var projection = Transform2D.viewport(800, 600)
private var width = 800
private var height = 600
private var projection = Transform2D.viewport(width, height)
private val shaderProgram = new ShaderProgram("general")
private val renderer = new InstanceRenderer[MeshVertex2D, MeshInstance2D](Mesh2D.quad, MeshInstance2D, shaderProgram)

View File

@ -9,7 +9,6 @@ import ocelot.desktop.ui.event.sources.{KeyEvents, MouseEvents, ScrollEvents}
import ocelot.desktop.ui.widget.{RootWidget, Widget}
import ocelot.desktop.util._
import ocelot.desktop.{OcelotDesktop, Settings}
import org.apache.commons.io.FileUtils
import org.apache.commons.lang3.SystemUtils
import org.lwjgl.BufferUtils
import org.lwjgl.input.Mouse
@ -20,7 +19,7 @@ import java.awt.datatransfer.{DataFlavor, StringSelection, UnsupportedFlavorExce
import java.io.{File, FileOutputStream}
import java.nio.ByteBuffer
import java.nio.channels.Channels
import java.nio.file.{Files, Paths}
import java.nio.file.Paths
import javax.imageio.ImageIO
import scala.collection.mutable
import scala.concurrent.duration.DurationInt
@ -195,9 +194,8 @@ object UiHandler extends Logging {
Display.create((new PixelFormat).withSRGB(true), new ContextAttribs(3, 2))
if (Settings.get.windowValidatePosition) {
if (Settings.get.windowValidatePosition)
fixInsaneInitialWindowGeometry()
}
KeyEvents.init()
MouseEvents.init()
@ -208,11 +206,13 @@ object UiHandler extends Logging {
logger.info(s"OpenGL version: ${GL11.glGetString(GL11.GL_VERSION)}")
Spritesheet.load()
graphics = new Graphics(scalingFactor)
graphics = new Graphics(Display.getWidth, Display.getHeight, scalingFactor)
if (Settings.get.audioDisable) {
logger.warn("Sound disabled (via config)")
} else {
}
else {
Audio.init()
}
}
@ -222,19 +222,8 @@ object UiHandler extends Logging {
root.relayout()
}
private var nativeLibrariesDir: String = _
def loadLibraries(): Unit = {
// we cannot remove DLL files on Windows after they were loaded by Ocelot
// therefore we will create them in local directory and keep for future
nativeLibrariesDir = if (SystemUtils.IS_OS_WINDOWS) {
Paths.get(this.getClass.getProtectionDomain.getCodeSource.getLocation.toURI.resolve("natives")).toString
} else {
val directory = Files.createTempDirectory("ocelot-desktop")
Runtime.getRuntime.addShutdownHook(new Thread(() => FileUtils.deleteDirectory(new File(nativeLibrariesDir))))
directory.toString
}
val librariesPath = OcelotPaths.libraries.toString
val arch = System.getProperty("os.arch")
val is64bit = arch.startsWith("amd64")
@ -254,9 +243,10 @@ object UiHandler extends Logging {
else
throw new Exception("Unsupported OS")
logger.debug("Unpacking native libraries to: " + nativeLibrariesDir)
logger.debug(s"Unpacking native libraries to: $librariesPath")
for (lib <- libs) {
val dest = new File(Paths.get(nativeLibrariesDir, lib).toString)
val dest = new File(Paths.get(librariesPath, lib).toString)
if (!dest.exists()) {
val source = getClass.getResourceAsStream("/" + lib)
@ -272,7 +262,7 @@ object UiHandler extends Logging {
}
}
System.setProperty("org.lwjgl.librarypath", nativeLibrariesDir)
System.setProperty("org.lwjgl.librarypath", librariesPath)
if (Settings.get.debugLwjgl) {
logger.info("Enabling LWJGL debug mode")
@ -362,7 +352,8 @@ object UiHandler extends Logging {
}
private def update(): Unit = {
if (shouldUpdateHierarchy) _updateHierarchy()
if (shouldUpdateHierarchy)
_updateHierarchy()
val mousePos = mousePosition
if (mousePos.x < 0 || mousePos.y < 0 || mousePos.x > root.width || mousePos.y > root.height) {

View File

@ -23,7 +23,9 @@ class RootWidget(setupDefaultWorkspace: Boolean = true) extends Widget {
val workspaceView = new WorkspaceView
workspaceView.root = root
if (setupDefaultWorkspace) workspaceView.createDefaultWorkspace()
if (setupDefaultWorkspace)
workspaceView.createDefaultWorkspace()
val modalDialogPool = new ModalDialogPool
val draggedItemPool = new DraggedItemPool

View File

@ -1,20 +1,19 @@
package ocelot.desktop.ui.widget.settings
import ocelot.desktop.color.Color
import ocelot.desktop.{ColorScheme, OcelotDesktop, Settings}
import ocelot.desktop.geometry.Padding2D
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.ui.layout.LinearLayout
import ocelot.desktop.ui.widget.modal.notification.{NotificationDialog, NotificationType}
import ocelot.desktop.ui.widget.{Button, IconButton, Label, PaddingBox, TextInput, Widget}
import ocelot.desktop.util.{FileUtils, Logging, Orientation}
import ocelot.desktop.ui.widget._
import ocelot.desktop.util.{FileUtils, Logging, OcelotPaths, Orientation}
import ocelot.desktop.{ColorScheme, OcelotDesktop, Settings}
import java.io.File
import javax.swing.JFileChooser
import scala.util.{Failure, Success, Try}
import scala.util.{Failure, Success}
class SystemSettingsTab extends SettingsTab with Logging {
private val OpenComputersConfigName = "opencomputers.conf"
private val OpenComputersConfigResource = "/application.conf"
override val icon: IconSource = IconSource.SettingsSystem
@ -22,9 +21,9 @@ class SystemSettingsTab extends SettingsTab with Logging {
children :+= new PaddingBox(new Label("OpenComputers configuration file path:"), Padding2D(bottom = 8))
private val textInput: TextInput = new TextInput(Settings.get.brainConfigPath.getOrElse("")) {
private val textInput: TextInput = new TextInput(Settings.get.brainCustomConfigPath.getOrElse("")) {
override def onInput(text: String): Unit = {
Settings.get.brainConfigPath = Some(text)
Settings.get.brainCustomConfigPath = Some(text)
restartWarning.isVisible = true
}
}
@ -60,15 +59,13 @@ class SystemSettingsTab extends SettingsTab with Logging {
children :+= new Button {
override def text: String = "Current Directory"
override def onClick(): Unit = {
unpackConfig(new File(OpenComputersConfigName))
unpackConfig(new File(OcelotPaths.openComputersConfigName))
}
}
children :+= new PaddingBox(new Button {
override def text: String = "Config Directory"
override def onClick(): Unit = {
val path = new File(FileUtils.getOcelotConfigDirectory.toFile, OpenComputersConfigName)
println(path)
unpackConfig(path)
unpackConfig(OcelotPaths.openComputersConfig.toFile)
}
}, Padding2D(left = 8))
children :+= new PaddingBox(new Button {
@ -112,7 +109,7 @@ class SystemSettingsTab extends SettingsTab with Logging {
}
private def setConfigPath(path: String): Unit = {
Settings.get.brainConfigPath = Some(path)
Settings.get.brainCustomConfigPath = Some(path)
textInput.setInput(path)
restartWarning.isVisible = true
}

View File

@ -1,12 +1,10 @@
package ocelot.desktop.util
import ocelot.desktop.Settings
import org.apache.commons.lang3.SystemUtils
import java.io.{File, FileOutputStream, IOException, RandomAccessFile}
import java.nio.ByteBuffer
import java.nio.channels.Channels
import java.nio.file.{Path, Paths}
import scala.util.{Try, Using}
object FileUtils extends Logging {
@ -40,9 +38,4 @@ object FileUtils extends Logging {
target
}
}
def getOcelotConfigDirectory: Path = {
if (SystemUtils.IS_OS_WINDOWS) Paths.get(System.getenv("APPDATA"), "Ocelot")
else Paths.get(System.getProperty("user.home"), ".config", "ocelot")
}
}

View File

@ -0,0 +1,44 @@
package ocelot.desktop.util
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.core.config.Configurator
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory
trait LoggingConfiguration {
{
val builder = ConfigurationBuilderFactory.newConfigurationBuilder()
// Console appender
val consoleAppender = builder.newAppender("console", "Console")
var patternLayout = builder.newLayout("PatternLayout")
patternLayout.addAttribute("pattern", "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n")
consoleAppender.add(patternLayout)
builder.add(consoleAppender)
// File
val fileAppender = builder.newAppender("file", "File")
fileAppender.addAttribute("fileName", OcelotPaths.desktopLog)
fileAppender.addAttribute("immediateFlush", false)
fileAppender.addAttribute("append", false)
patternLayout = builder.newLayout("PatternLayout")
patternLayout.addAttribute("pattern", "%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n")
fileAppender.add(patternLayout)
builder.add(fileAppender)
// Root logger
val rootLogger = builder.newRootLogger(Level.DEBUG)
rootLogger.add(builder.newAppenderRef("console"))
rootLogger.add(builder.newAppenderRef("file"))
builder.add(rootLogger)
// Webcam logger, required for Camera node from Computronix
val webcamLogger = builder.newLogger("com.github.sarxos.webcam", Level.INFO)
builder.add(webcamLogger)
Configurator.initialize(builder.build)
}
}

View File

@ -0,0 +1,45 @@
package ocelot.desktop.util
import org.apache.commons.lang3.SystemUtils
import java.nio.file.{Path, Paths}
object OcelotPaths {
def windowsAppDataDirectoryName: String = System.getenv("APPDATA")
def linuxHomeDirectoryName: String = System.getProperty(SystemUtils.USER_HOME)
def openComputersConfigName: String = {
if (SystemUtils.IS_OS_WINDOWS)
"OpenComputers.conf"
else
"opencomputers.conf"
}
def libraries: Path = {
if (SystemUtils.IS_OS_WINDOWS)
Paths.get(windowsAppDataDirectoryName, "Ocelot", "Libraries")
else
Paths.get(linuxHomeDirectoryName, ".local", "lib", "ocelot")
}
def openComputersConfig: Path = {
if (SystemUtils.IS_OS_WINDOWS)
Paths.get(windowsAppDataDirectoryName, "Ocelot", "Config", openComputersConfigName)
else
Paths.get(linuxHomeDirectoryName, ".config", "ocelot", openComputersConfigName)
}
def desktopConfig: Path = {
if (SystemUtils.IS_OS_WINDOWS)
Paths.get(windowsAppDataDirectoryName, "Ocelot", "Config", "Desktop.conf")
else
Paths.get(linuxHomeDirectoryName, ".config", "ocelot", "desktop.conf")
}
def desktopLog: Path = {
if (SystemUtils.IS_OS_WINDOWS)
Paths.get(windowsAppDataDirectoryName, "Ocelot", "Logs", "Desktop.log")
else
Paths.get(linuxHomeDirectoryName, ".local", "share", "ocelot", "desktop.log")
}
}

View File

@ -15,7 +15,7 @@ class SettingsData {
updateWith(data)
}
var brainConfigPath: Option[String] = None
var brainCustomConfigPath: Option[String] = None
var volumeMaster: Float = 1f
var volumeBeep: Float = 1f