Skip to content
Permalink
Browse files

Add worldfs to CC

  • Loading branch information...
timia2109 committed Aug 14, 2018
1 parent 914df8b commit 0b26c6216426eeba7e2555e522049d02393536f3
@@ -154,6 +154,9 @@

public static int maxNotesPerTick = 8;

public static int worldfsLimit = floppySpaceLimit;
public static boolean worldfs_enable = false;

// Blocks and Items
public static class Blocks
{
@@ -223,6 +226,9 @@
public static Property maximumFilesOpen;
public static Property maxNotesPerTick;

public static Property worldfsLimit;
public static Property worldfs_enable;

}

// Registries
@@ -344,6 +350,12 @@ public void preInit( FMLPreInitializationEvent event )
Config.maxNotesPerTick = Config.config.get( Configuration.CATEGORY_GENERAL, "maxNotesPerTick", maxNotesPerTick );
Config.maxNotesPerTick.setComment( "Maximum amount of notes a speaker can play at once" );

Config.worldfs_enable = Config.config.get( Configuration.CATEGORY_GENERAL, "worldfs_enable", worldfs_enable );
Config.worldfs_enable.setComment( "Enable the \"worldfs\" API " );

Config.worldfsLimit = Config.config.get( Configuration.CATEGORY_GENERAL, "worldfsLimit", worldfsLimit );
Config.worldfsLimit.setComment( "The worldfs space limit for a worldfs channel, in bytes" );

for (Property property : Config.config.getCategory( Configuration.CATEGORY_GENERAL ).getOrderedValues())
{
property.setLanguageKey( "gui.computercraft:config." + CaseFormat.LOWER_CAMEL.to( CaseFormat.LOWER_UNDERSCORE, property.getName() ) );
@@ -387,6 +399,9 @@ public static void syncConfig() {

maxNotesPerTick = Math.max(1, Config.maxNotesPerTick.getInt());

worldfs_enable = Config.worldfs_enable.getBoolean();
worldfsLimit = Config.worldfsLimit.getInt();

Config.config.save();
}

@@ -0,0 +1,110 @@
package dan200.computercraft.core.apis;

import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.core.filesystem.FileSystemException;
import dan200.computercraft.core.filesystem.WorldFSWrapper;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;

import java.util.HashMap;
import java.util.Map;

public class WorldFSAPI implements ILuaAPI {

private Map<String, WorldFSWrapper> mounted_wfs;
private IAPIEnvironment m_api_enviroment;

public WorldFSAPI(IAPIEnvironment iapiEnvironment) {
m_api_enviroment = iapiEnvironment;
mounted_wfs = new HashMap<>();
}

private void mount(String label, String channel) throws LuaException{
if (!mounted_wfs.containsKey(channel)) {
WorldFSWrapper worldFSWrapper = new WorldFSWrapper(label, channel, m_api_enviroment.getFileSystem(), m_api_enviroment.getComputerEnvironment());
mounted_wfs.put(channel, worldFSWrapper);
try {
worldFSWrapper.mount();
} catch (FileSystemException fse) {
throw new LuaException("Error on mounting: "+fse.getMessage());
}
}
else {
throw new LuaException(
String.format("Error worldfs %s is already mounted under %s", channel, mounted_wfs.get(channel).getPath())
);
}
}

private void unmount(String channel) throws LuaException {
if (mounted_wfs.containsKey(channel)) {
mounted_wfs.get(channel).unmount();
mounted_wfs.remove(channel);
}
else {
throw new LuaException(
String.format("%s is not mounted", channel)
);
}
}

@Override
public String[] getNames() {
return new String[]{
"worldfs"
};
}

@Override
public void startup() {
mounted_wfs.clear();
}

@Override
public void advance(double _dt) {

}

@Override
public void shutdown() {
for (WorldFSWrapper mount : mounted_wfs.values()) {
mount.unmount();
}
mounted_wfs.clear();
}

@Override
public String[] getMethodNames() {
return new String[]{
"mount",
"unmount",
"list"
};
}

@Override
public Object[] callMethod(ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException {
switch (method) {
case 0: // worldfs.mount(string, string)
String channel = getString(arguments, 0);
String label = getString(arguments, 1);

mount(label, channel);
break;
case 1: // worldfs.unmount(string)
String channel2 = getString(arguments, 0);

unmount(channel2);
break;
case 2: // worldfs.list()
Map<Object,Object> list = new HashMap<>();
int i=1;
for (WorldFSWrapper wrapper : mounted_wfs.values()) {
list.put(i++, wrapper);
}
return new Object[]{list};
}

return null;
}
}
@@ -617,6 +617,9 @@ private void createAPIs()
{
m_apis.add( new HTTPAPI( m_apiEnvironment ) );
}
if (ComputerCraft.worldfs_enable) {
m_apis.add( new WorldFSAPI( m_apiEnvironment ) );
}
}

private void initLua()
@@ -0,0 +1,98 @@
package dan200.computercraft.core.filesystem;

import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.ILuaObject;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.core.computer.IComputerEnvironment;
import dan200.computercraft.shared.computer.core.IComputer;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

public class WorldFSWrapper implements ILuaObject {

// Chars to create the Key
private static final String CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

private String m_channelname;
private String m_channelkey;
private String m_path;
private FileSystem m_fs;
private IComputerEnvironment m_computerEnvironment;

public WorldFSWrapper(String label, String channel, FileSystem fs, IComputerEnvironment computerEnvironment) {
m_channelname = channel;
m_channelkey = nameToKey(channel);
m_path = label;
m_computerEnvironment = computerEnvironment;
m_fs = fs;
}

public void mount() throws FileSystemException{
m_fs.mountWritable(m_path, m_path, getWritableMount());
}

public void unmount() {
m_fs.unmount(m_path);
}

public String getPath() {
return m_path;
}

public IWritableMount getWritableMount() {
return m_computerEnvironment.createSaveDirMount("computer/worldfs/"+m_channelkey, ComputerCraft.worldfsLimit);
}

private static String nameToKey(String name) {
StringBuilder stringBuilder = new StringBuilder();
char[] keyChars = CHARS.toCharArray();

try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(name.getBytes(StandardCharsets.UTF_8));

for (byte b : hash) {
stringBuilder.append(
keyChars[ Math.abs( b % keyChars.length )]
);
}
} catch (NoSuchAlgorithmException no) {
// Then we have some other problems...
no.printStackTrace();
}

return stringBuilder.toString();
}

@Override
public String[] getMethodNames() {
return new String[]{
"getChannel",
"getPath",
"getKey"
};
}

@Override
public Object[] callMethod(ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException {
switch (method) {
case 0: // getChannel
return new Object[]{m_channelname};
case 1: // getPath
return new Object[]{m_path};
case 2: // getKey
return new Object[]{m_channelkey};
}
return null;
}
}
@@ -33,6 +33,7 @@ New Features in ComputerCraft 1.80:
* Added speaker block, turtle upgrade, pocket upgrade, and peripheral api
* Startup can now be a directory containing multiple startup files
* Added .getLabel to the computer peripheral
* Added worldfs api to create global file shares

New Features in ComputerCraft 1.79:

@@ -33,5 +33,6 @@ New Features in ComputerCraft 1.80:
* Added speaker block, turtle upgrade, pocket upgrade, and peripheral api
* Startup can now be a directory containing multiple startup files
* Added .getLabel to the computer peripheral
* Added worldfs api to create global file shares

Type "help changelog" to see the full version history.
@@ -0,0 +1,6 @@
worldfs is a program to quickly access the worldfs methods

ex:
worldfs list
worldfs mount <channelname> <mount_path>
worldfs unmount <channelname>
@@ -0,0 +1,5 @@
worldfs api is an api to communicate with the worldfs.
Functions in the worldfs API:
worldfs.list()
worldfs.mount( [channelname], [mountpath] )
worldfs.unmount( [channelname] )
@@ -0,0 +1,48 @@
local function printUsage()
print("Usage:")
print("worldfs list")
print("worldfs mount <channel> <label>")
print("worldfs unmount <channel>")
end

if not worldfs then
printError( "worldfs requires worldfs API" )
printError( "Set worldfs_enable to true in ComputerCraft.cfg" )
return
end

local targs = {...}
if #targs < 1 then
printUsage()
return
end

if targs[1] == "list" then
local tlist = worldfs.list()
if #tlist == 0 then
print("No worldfs drives mounted")
return
end
local twrap = {
colors.yellow,
{"Channel", "Path", "Key"},
colors.white
}
for k,value in ipairs(tlist) do
local key = string.sub(value.getKey(), 1, 10) .. "..."
table.insert(twrap, {
value.getChannel(),
value.getPath(),
key
})
end
textutils.tabulate( unpack(twrap) )
elseif targs[1] == "mount" and #targs >= 3 then
worldfs.mount(targs[2], targs[3])
print("mounted worldfs " .. targs[2] .. " under /"..targs[3])
elseif targs[1] == "unmount" and #targs >= 2 then
worldfs.unmount(targs[2])
print("unmounted worldfs "..targs[2])
else
printUsage()
end
@@ -21,6 +21,9 @@ end
if http then
sPath = sPath..":/rom/programs/http"
end
if worldfs then
sPath = sPath..":/rom/programs/worldfs"
end
shell.setPath( sPath )
help.setPath( "/rom/help" )

@@ -231,6 +234,16 @@ if turtle then
shell.setCompletionFunction( "rom/programs/turtle/unequip.lua", completeUnequip )
end

if worldfs then
local tWorldFsOptions = { "list", "mount", "unmount"}
local function completeWorldFs(shell, nIndex, sText)
if nIndex == 1 then
return completeMultipleChoice(sText, tWorldFsOptions)
end
end
shell.setCompletionFunction("rom/programs/worldfs/worldfs.lua", completeWorldFs)
end


-- Run autorun files
if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then

0 comments on commit 0b26c62

Please sign in to comment.
You can’t perform that action at this time.