mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 02:12:42 -04:00
new filesystem device feature, locked mode
A locked filesystem is readonly (in either managed or unmanaged modes) It cannot be unlocked unless its mode is switched or it is recrafted - both actions wipe the drive. The data is thus "locked" or protected unless the drive is wiped. The player's displace name is also recorded and shown in tooltips on the device to indicate who locked it. In this manner, data authenticity can be trusted closes #2138
This commit is contained in:
parent
ed99a18944
commit
2611ecb265
@ -203,6 +203,8 @@ oc:gui.Chat.WarningRecipes=There were errors loading one or more recipes. Some i
|
||||
oc:gui.Chat.WarningSimpleComponent=An addon (yours?) using the §aSimpleComponent§f interface did §esomething wrong§f. Component logic could not be injected. Please check your log file for more information.
|
||||
oc:gui.Drive.Managed=Managed
|
||||
oc:gui.Drive.Unmanaged=Unmanaged
|
||||
oc:gui.Drive.ReadOnlyLock=Lock
|
||||
oc:gui.Drive.ReadOnlyLockWarning=§lRead Only§r lock. Cannot be removed unless the drive is wiped.
|
||||
oc:gui.Drive.Warning=§lWarning§r: switching modes will result in a loss of all data currently stored on the disk!
|
||||
oc:gui.Error.ComponentOverflow=Too many components connected to the computer.
|
||||
oc:gui.Error.InternalError=Internal error, please see the log file. This is probably a bug.
|
||||
@ -289,6 +291,7 @@ oc:tooltip.DiskDrive.CC=ComputerCraft floppies are §asupported§7.
|
||||
oc:tooltip.DiskDrive=Allows reading and writing floppies. Can be installed in robots to allow inserting floppies later on.
|
||||
oc:tooltip.DiskDriveMountable=Provides the same functionality as a normal disk drive, but must be installed in a rack.
|
||||
oc:tooltip.DiskUsage=Disk usage: %s/%s Byte
|
||||
oc:tooltip.DiskLocked=Locked by: %s
|
||||
oc:tooltip.DiskModeManaged=Mode: Managed
|
||||
oc:tooltip.DiskModeUnmanaged=Mode: Unmanaged
|
||||
oc:tooltip.Drone=Drones are light-weight, fast reconnaissance units with limited cargo space.
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 764 B |
@ -116,6 +116,10 @@ object Localization {
|
||||
def Unmanaged = localizeImmediately("gui.Drive.Unmanaged")
|
||||
|
||||
def Warning = localizeImmediately("gui.Drive.Warning")
|
||||
|
||||
def ReadOnlyLock = localizeImmediately("gui.Drive.ReadOnlyLock")
|
||||
|
||||
def LockWarning = localizeImmediately("gui.Drive.ReadOnlyLockWarning")
|
||||
}
|
||||
|
||||
object Raid {
|
||||
@ -159,6 +163,8 @@ object Localization {
|
||||
|
||||
def DiskMode(isUnmanaged: Boolean) = localizeImmediately(if (isUnmanaged) "tooltip.DiskModeUnmanaged" else "tooltip.DiskModeManaged")
|
||||
|
||||
def DiskLock(lockInfo: String): String = if (lockInfo.isEmpty) "" else localizeImmediately("tooltip.DiskLocked", lockInfo)
|
||||
|
||||
def Materials = localizeImmediately("tooltip.Materials")
|
||||
|
||||
def Tier(tier: Int) = localizeImmediately("tooltip.Tier", tier.toString)
|
||||
|
@ -34,6 +34,12 @@ object PacketSender {
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendDriveLock(): Unit = {
|
||||
val pb = new SimplePacketBuilder(PacketType.DriveLock)
|
||||
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendDronePower(e: Drone, power: Boolean) {
|
||||
val pb = new SimplePacketBuilder(PacketType.DronePower)
|
||||
|
||||
|
@ -10,19 +10,21 @@ import net.minecraft.entity.player.InventoryPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class Drive(playerInventory: InventoryPlayer, val driveStack: () => ItemStack) extends GuiScreen with traits.Window {
|
||||
override val windowHeight = 85
|
||||
override val windowHeight = 120
|
||||
|
||||
override def backgroundImage = Textures.guiDrive
|
||||
|
||||
protected var managedButton: ImageButton = _
|
||||
protected var unmanagedButton: ImageButton = _
|
||||
protected var lockedButton: ImageButton = _
|
||||
|
||||
protected override def actionPerformed(button: GuiButton) {
|
||||
if (button.id == 0) {
|
||||
ClientPacketSender.sendDriveMode(false)
|
||||
}
|
||||
if (button.id == 1) {
|
||||
} else if (button.id == 1) {
|
||||
ClientPacketSender.sendDriveMode(true)
|
||||
} else if (button.id == 2) {
|
||||
ClientPacketSender.sendDriveLock()
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,18 +32,24 @@ class Drive(playerInventory: InventoryPlayer, val driveStack: () => ItemStack) e
|
||||
super.initGui()
|
||||
managedButton = new ImageButton(0, guiLeft + 11, guiTop + 11, 74, 18, Textures.guiButtonDriveMode, text = Localization.Drive.Managed, textColor = 0x608060, canToggle = true)
|
||||
unmanagedButton = new ImageButton(1, guiLeft + 91, guiTop + 11, 74, 18, Textures.guiButtonDriveMode, text = Localization.Drive.Unmanaged, textColor = 0x608060, canToggle = true)
|
||||
lockedButton = new ImageButton(2, guiLeft + 11, guiTop + windowHeight - 42, 44, 18, Textures.guiButtonDriveMode, text = Localization.Drive.ReadOnlyLock, textColor = 0x608060, canToggle = true)
|
||||
add(buttonList, managedButton)
|
||||
add(buttonList, unmanagedButton)
|
||||
add(buttonList, lockedButton)
|
||||
}
|
||||
|
||||
override def updateScreen(): Unit = {
|
||||
unmanagedButton.toggled = new DriveData(driveStack()).isUnmanaged
|
||||
val data = new DriveData(driveStack())
|
||||
unmanagedButton.toggled = data.isUnmanaged
|
||||
managedButton.toggled = !unmanagedButton.toggled
|
||||
lockedButton.toggled = data.isLocked
|
||||
lockedButton.enabled = !data.isLocked
|
||||
super.updateScreen()
|
||||
}
|
||||
|
||||
override def drawScreen(mouseX: Int, mouseY: Int, dt: Float): Unit = {
|
||||
super.drawScreen(mouseX, mouseY, dt)
|
||||
fontRendererObj.drawSplitString(Localization.Drive.Warning, guiLeft + 7, guiTop + 37, xSize - 16, 0x404040)
|
||||
fontRendererObj.drawSplitString(Localization.Drive.Warning, guiLeft + 11, guiTop + 37, xSize - 20, 0x404040)
|
||||
fontRendererObj.drawSplitString(Localization.Drive.LockWarning, guiLeft + 61, guiTop + windowHeight - 48, xSize - 68, 0x404040)
|
||||
}
|
||||
}
|
@ -73,6 +73,7 @@ object PacketType extends Enumeration {
|
||||
// Client -> Server
|
||||
ComputerPower,
|
||||
CopyToAnalyzer,
|
||||
DriveLock,
|
||||
DriveMode,
|
||||
DronePower,
|
||||
KeyDown,
|
||||
|
@ -11,12 +11,24 @@ class DriveData extends ItemData(null) {
|
||||
}
|
||||
|
||||
var isUnmanaged = false
|
||||
var lockInfo: String = ""
|
||||
|
||||
def isLocked: Boolean = {
|
||||
lockInfo != null && !lockInfo.isEmpty
|
||||
}
|
||||
|
||||
private val UnmanagedKey = Settings.namespace + "unmanaged"
|
||||
private val LockKey = Settings.namespace + "lock"
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
isUnmanaged = nbt.getBoolean(Settings.namespace + "unmanaged")
|
||||
isUnmanaged = nbt.getBoolean(UnmanagedKey)
|
||||
lockInfo = if (nbt.hasKey(LockKey)) {
|
||||
nbt.getString(LockKey)
|
||||
} else ""
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
nbt.setBoolean(Settings.namespace + "unmanaged", isUnmanaged)
|
||||
nbt.setBoolean(UnmanagedKey, isUnmanaged)
|
||||
nbt.setString(LockKey, lockInfo)
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import li.cil.oc.Localization
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.item.data.DriveData
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.world.World
|
||||
@ -31,7 +32,9 @@ trait FileSystemLike extends Delegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
tooltip.add(Localization.Tooltip.DiskMode(nbt.getBoolean(Settings.namespace + "unmanaged")))
|
||||
val data = new DriveData(stack)
|
||||
tooltip.add(Localization.Tooltip.DiskMode(data.isUnmanaged))
|
||||
tooltip.add(Localization.Tooltip.DiskLock(data.lockInfo))
|
||||
}
|
||||
super.tooltipLines(stack, player, tooltip, advanced)
|
||||
}
|
||||
|
@ -70,10 +70,13 @@ object DriverFileSystem extends Item {
|
||||
val sound = Settings.resourceDomain + ":" + (if (isFloppy) "floppy_access" else "hdd_access")
|
||||
val drive = new DriveData(stack)
|
||||
val environment = if (drive.isUnmanaged) {
|
||||
new Drive(capacity max 0, platterCount, label, Option(host), Option(sound), speed)
|
||||
new Drive(capacity max 0, platterCount, label, Option(host), Option(sound), speed, drive.isLocked)
|
||||
}
|
||||
else {
|
||||
val fs = oc.api.FileSystem.fromSaveDirectory(address, capacity max 0, Settings.get.bufferChanges)
|
||||
var fs = oc.api.FileSystem.fromSaveDirectory(address, capacity max 0, Settings.get.bufferChanges)
|
||||
if (drive.isLocked) {
|
||||
fs = oc.api.FileSystem.asReadOnly(fs)
|
||||
}
|
||||
oc.api.FileSystem.asManagedEnvironment(fs, label, host, sound, speed)
|
||||
}
|
||||
if (environment != null && environment.node != null) {
|
||||
|
@ -35,6 +35,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
p.packetType match {
|
||||
case PacketType.ComputerPower => onComputerPower(p)
|
||||
case PacketType.CopyToAnalyzer => onCopyToAnalyzer(p)
|
||||
case PacketType.DriveLock => onDriveLock(p)
|
||||
case PacketType.DriveMode => onDriveMode(p)
|
||||
case PacketType.DronePower => onDronePower(p)
|
||||
case PacketType.KeyDown => onKeyDown(p)
|
||||
@ -86,13 +87,34 @@ object PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
def onDriveMode(p: PacketParser) = p.player match {
|
||||
def onDriveLock(p: PacketParser) = p.player match {
|
||||
case player: EntityPlayerMP =>
|
||||
Delegator.subItem(player.getHeldItem) match {
|
||||
case Some(drive: FileSystemLike) =>
|
||||
val data = new DriveData(player.getHeldItem)
|
||||
data.isUnmanaged = p.readBoolean()
|
||||
data.lockInfo = player.getDisplayName match {
|
||||
case name: String if name != null && !name.isEmpty => name
|
||||
case _ => "notch" // meaning: "unknown"
|
||||
}
|
||||
data.save(player.getHeldItem)
|
||||
case _ => // Invalid packet
|
||||
}
|
||||
case _ => // Invalid Packet
|
||||
}
|
||||
|
||||
def onDriveMode(p: PacketParser) = p.player match {
|
||||
case player: EntityPlayerMP =>
|
||||
val heldItem = player.getHeldItem
|
||||
Delegator.subItem(heldItem) match {
|
||||
case Some(drive: FileSystemLike) =>
|
||||
val data = new DriveData(heldItem)
|
||||
val newIsUnmanaged = p.readBoolean()
|
||||
if (data.isUnmanaged != newIsUnmanaged) {
|
||||
fs.FileSystem.removeAddress(heldItem)
|
||||
data.lockInfo = ""
|
||||
}
|
||||
data.isUnmanaged = newIsUnmanaged
|
||||
data.save(heldItem)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
case _ => // Invalid packet.
|
||||
|
@ -28,7 +28,7 @@ import net.minecraftforge.common.DimensionManager
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
|
||||
class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Option[EnvironmentHost], val sound: Option[String], val speed: Int) extends prefab.ManagedEnvironment with DeviceInfo {
|
||||
class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Option[EnvironmentHost], val sound: Option[String], val speed: Int, val isLocked: Boolean) extends prefab.ManagedEnvironment with DeviceInfo {
|
||||
override val node = Network.newNode(this, Visibility.Network).
|
||||
withComponent("drive", Visibility.Neighbors).
|
||||
withConnector().
|
||||
@ -74,6 +74,7 @@ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Op
|
||||
|
||||
@Callback(doc = """function(value:string):string -- Sets the label of the drive. Returns the new value, which may be truncated.""")
|
||||
def setLabel(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
|
||||
if (isLocked) throw new Exception("drive is read only")
|
||||
if (label == null) throw new Exception("drive does not support labeling")
|
||||
if (args.checkAny(0) == null) label.setLabel(null)
|
||||
else label.setLabel(args.checkString(0))
|
||||
@ -101,6 +102,7 @@ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Op
|
||||
|
||||
@Callback(direct = true, doc = """function(sector:number, value:string) -- Write the specified contents to the specified sector.""")
|
||||
def writeSector(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
|
||||
if (isLocked) throw new Exception("drive is read only")
|
||||
context.consumeCallBudget(writeSectorCosts(speed))
|
||||
val sectorData = args.checkByteArray(1)
|
||||
val sector = moveToSector(context, checkSector(args, 0))
|
||||
@ -120,6 +122,7 @@ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Op
|
||||
|
||||
@Callback(direct = true, doc = """function(offset:number, value:number) -- Write a single byte to the specified offset.""")
|
||||
def writeByte(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
|
||||
if (isLocked) throw new Exception("drive is read only")
|
||||
context.consumeCallBudget(writeByteCosts(speed))
|
||||
val offset = args.checkInteger(0) - 1
|
||||
val value = args.checkInteger(1).toByte
|
||||
|
@ -11,6 +11,8 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.fs.Label
|
||||
import li.cil.oc.api.network.EnvironmentHost
|
||||
import li.cil.oc.common.item.Delegator
|
||||
import li.cil.oc.common.item.traits.FileSystemLike
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.computercraft.DriverComputerCraftMedia
|
||||
import li.cil.oc.server.component
|
||||
@ -112,6 +114,23 @@ object FileSystem extends api.detail.FileSystemAPI {
|
||||
else null
|
||||
}
|
||||
|
||||
def removeAddress(fsStack: ItemStack): Boolean = {
|
||||
Delegator.subItem(fsStack) match {
|
||||
case Some(drive: FileSystemLike) => {
|
||||
val data = li.cil.oc.integration.opencomputers.Item.dataTag(fsStack)
|
||||
if (data.hasKey("node")) {
|
||||
val nodeData = data.getCompoundTag("node")
|
||||
if (nodeData.hasKey("address")) {
|
||||
nodeData.removeTag("address")
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
def fromMemory(capacity: Long): api.fs.FileSystem = new RamFileSystem(capacity)
|
||||
|
||||
def fromComputerCraft(mount: AnyRef): api.fs.FileSystem =
|
||||
|
Loading…
x
Reference in New Issue
Block a user