Jump to content


The Crazy Phoenix's Content

There have been 73 items by The Crazy Phoenix (Search limited from 10-February 22)


By content type

See this member's


Sort by                Order  

#269112 Webserver crossing dimensions.

Posted by The Crazy Phoenix on 19 August 2017 - 01:22 PM in Ask a Pro

For players who don't have chunk loaders, you can also place the computer inside a spawn chunk. Spawn chunks are always loaded.



#269098 Corrupt-A-Wish!

Posted by The Crazy Phoenix on 18 August 2017 - 11:39 PM in Forum Games

Granted. The potato gives people stronger superpowers the more they want to kill you.

I wish religions and cults no longer existed.



#268977 Condition for a door system

Posted by The Crazy Phoenix on 12 August 2017 - 03:48 PM in Ask a Pro

Bomb Bloke's suggestion will return true if the inserted disk is a floppy disk or a music disk.
If you want to tell them apart, use disk.hasData("sideDriveIsOn") (returns true if a floppy disk is inserted).



#268950 Stargate program won't update screen?

Posted by The Crazy Phoenix on 11 August 2017 - 05:26 AM in Ask a Pro

You're pulling the mouse_click event before writing to the screen. Os.pullEvent doesn't return until it pulls at an event.
Move your os.pullEvent to just before the "if y == 6 then" line.

Sleep(0.1) is also unnecessary because os.pullEvent will yield the program.



#268948 Problems with string and variables (exporting program)

Posted by The Crazy Phoenix on 11 August 2017 - 05:20 AM in Ask a Pro

View PostDave-ee Jones, on 10 August 2017 - 10:33 PM, said:

-snip-

You literally just copied my post..

It's just a different way of explaining the difference between variable names and string literals. Even though I already understood the subject, I personally found it clearer.



#268923 Problems with string and variables (exporting program)

Posted by The Crazy Phoenix on 10 August 2017 - 07:02 AM in Ask a Pro

What's wrong with setting selDrive = response1 (or replacing all instances of selDrive with response1)?

If you want to validate the user's input, try disk.hasData(response1). If it returns true, that means that the disk drive exists and contains a floppy disk.



#268898 Remote controlling a computer

Posted by The Crazy Phoenix on 09 August 2017 - 09:10 PM in Ask a Pro

View PostDave-ee Jones, on 09 August 2017 - 03:49 AM, said:

Okay, so, you're talking about redirecting the server's drawing functions to the client? I was looking through some RC programs and a lot of them seem to create custom 'term' functions that actually just redirect the output to a rednet/modem message, which makes sense I guess but that means the server doesn't have the same screen as the client, they should have consistent screens e.g. for remote help or showing someone how to program a certain function in a program, or even just remotely controlling a monitor.

In regards to inconsistent screen sizes I figured that the screens would have to be downsized to be consistent (well, virtually consistent).

If you want the same screen, then just call the server's term functions when you transmit to the client. For example...

-- Set modem, tch, rch here
local server_term = term.current()
local custom_term = {}
for name, func in pairs(server_term) do
	custom_term[name] = function(...)
		modem.transmit(tch, rch, {name = name, args = {...}})
		return func(...)
	end
end
term.redirect(custom_term)  -- Used to be current_term (it was a mistake)
-- Wait for the client to be running here
term.clear()
term.setCursorPos(1, 1)
-- Run program of choice here

Instead of only transmitting. This sample will work if the client's screen is not smaller in at least one dimension.
You can use term functions that aren't the current term, you just use their table as if it were the term API (without redirect, native and current of course).



#268887 Remote controlling a computer

Posted by The Crazy Phoenix on 09 August 2017 - 01:52 AM in Ask a Pro

Problem 1: Not a true "problem", merely an illusion.

Solution 1: Drawing is done pixel-by-pixel regardless so the client doesn't need the GUI code. Even then, function wrapping allows one to know what functions are being called. It's simply a matter of calling on the client the matching function when called on the server (after syncing the screens of course)
For example, create a custom term table that wraps each term function by also sending the called function to the client, which simply calls them as it receives them. Then, you'd call term.redirect on that table to make term functions use it instead.

Problem 2: Depends on problem 1, therefore not an actual issue.

Solution 2: If it were an issue, the program could be transmitted from the server to the client, allowing the client to run the exact same program regardless of its local copy.

Problem 3: Somewhat of an issue, but the cause is misunderstood.

Solution 3: The mouse events contain information about the pixel touched. If the server's screen is bigger, you'd simply force the server to run at a lower resolution by changing term.getSize (ideally through redirection). If the screens aren't the same size, you can then simply discard mouse events that are out of bounds on the resized screen. On the server, this would be done by overriding os.pullEventRaw.



#268876 Clear computer memory?

Posted by The Crazy Phoenix on 08 August 2017 - 01:11 PM in Ask a Pro

I added a table that maps every table to its copy to fix the issue with the recursion. It should even work on indirect recursion ("a contains b and b contains a" instead of simply "a contains a").
The function wrapper is the only way of preventing people from changing the environment of the original function.
Perhaps load and string.dump might be the only way of fixing both issues.

local env = {}
local tcp = {{_G, env}}
local cpd = {[_G] = env}
while #tcp > 0 do
	local current = tcp[#tcp]
	tcp[#tcp] = nil
	for key, value in pairs(current[1]) do
		if type(value) == "table" then
			if cpd[value] then
				current[2][key] = cpd[value]
			else
				current[2][key] = {}
				tcp[#tcp + 1] = {value, current[2][key]}
				cpd[value] = current[2][key]
			end
		elseif type(value) == "function" then
			current[2][key] = function()
				_ENV = env
				value()
			end
			-- You can use setfenv but it will modify the original function.
		else
			current[2][key] =  value
		end
	end
end



#268871 Potential Computercraft Bug

Posted by The Crazy Phoenix on 08 August 2017 - 11:23 AM in Ask a Pro

Instead of using sleep(0.3), use a timer. That will allow you to have it continuously blink without spamming the network.
In fact, you don't even need multithreading if you listen to the rednet_message or modem_message event.

local timer = os.startTimer(0.3)
local fuel = false
local state = false
while true do
	local event, data, msg = os.pullEvent()
	if event == "rednet_message" and data == 7 then
		fuel = msg == "fuelLow" and true or (msg == "fuelGood" and false or fuel)
	elseif event == "timer" and data == timer then
		if fuel then
			state = not state
			rs.setOutput("left", state)
		else
			-- No delay next time fuel is low.
			state = false
		end
		timer = os.startTimer(0.3)
	end
end



#268866 Clear computer memory?

Posted by The Crazy Phoenix on 08 August 2017 - 10:09 AM in Ask a Pro

View PostBomb Bloke, on 08 August 2017 - 01:48 AM, said:

View PostThe Crazy Phoenix, on 07 August 2017 - 07:02 PM, said:

However, it is still possible to clear the RAM by manipulating the subprograms' environment table.

Creating a system that allows a full reset without a reboot would be much trickier. Function environments, as well as sub-tables within _G, won't reset that way.

Is there anything more than deep copying the global environment?

local env = {}
local tcp = {{_G, env}}
while #tcp > 0 do
	local current = tcp[#tcp]
	tcp[#tcp] = nil
	for key, value in pairs(current[1]) do
		if type(value) == "table" then
			tcp[#tcp + 1] = {value, current[2][key]}
		elseif type(value) == "function" then
			current[2][key] = function()
				_ENV = env
				value()
			end
			-- You can use setfenv but it will modify the original function.
		else
			current[2][key] =  value
		end
	end
end



#268865 Potential Computercraft Bug

Posted by The Crazy Phoenix on 08 August 2017 - 09:39 AM in Ask a Pro

Check your code for illegal characters, it seems that there is an 0xA0 character before every single indented line.

Instead of using a shared variable and repeatedly checking, use os.queueEvent and os.pullEvent to signal to the alert function what it should do.



#268854 Get file from GitHub

Posted by The Crazy Phoenix on 07 August 2017 - 07:04 PM in Ask a Pro

View PostJummit, on 07 August 2017 - 08:56 AM, said:

So here is the code i would use:
local website = http.get(url)
if website then
   github_file = website.readAll()
end
website.close()

That would still error if website == nil.

local website = http.get(url)
if website then
    github_file = website.readAll()
    website.close()
end



#268853 Clear computer memory?

Posted by The Crazy Phoenix on 07 August 2017 - 07:02 PM in Ask a Pro

As Bomb Bloke has already pointed out, it is not possible to do that.

However, it is still possible to clear the RAM by manipulating the subprograms' environment table.

local mt = {__index = _G, __metatable = function() return nil end}
while true do
    local env = {}
    env._G = env
    setmetatable(env, mt)
    os.run(env, multishell and "/rom/programs/advanced/multishell" or "/rom/programs/shell")
end

That will reset the environment and restart the shell every time the shell is exited.



#268851 Using HTTP to gather a variable in php to process in lua

Posted by The Crazy Phoenix on 07 August 2017 - 06:53 PM in Ask a Pro

View PostTwijn, on 09 July 2017 - 11:10 PM, said:

The code sample provided by KingofGamesYami should work fine. The one issue with that one is that it'll, in addition to returning false if the current version number is below the latest version, it'll also say if the current version number is above the latest version. This, in many cases, won't be an issue, but if you do push the program version above the one that's being returned by the website, it will in fact appear to be out of date. A way to prevent this is by using tonumber() to turn the version into a number before comparison and using >=/<=, though note this obviously won't work correctly if your version is laid out like 1.0.1.
(Note: Even in that case, you could remove all of the '.' in lua; though this would mean you'd have to keep the format consistent. Ie, you couldn't move from 1.0 to 1.0.1 or 1.0.0 to 1.0.01 without potentially causing issues. (like from going from 1.0.11 from 1.0.2, you'd have to put 1.0.20 as it'd be comparing 1011 to 102)


I've set up these two samples to hopefully demonstrate this & help your understanding:

First webpage
https://cc.tylertwin...var/1point0.php

<?php
  header("Content-Type: text/plain");
  echo "1.0";
?>

Second webpage
https://cc.tylertwin...var/1point1.php

<?php
  header("Content-Type: text/plain");
  echo "1.1";
?>

Lua:

pastebin run 1VZga5iN
This will check both versions and tell if they're up to date with the default version (1.0). You can additionally run `pastebin run 1VZga5iN 1.1` and you'll see the issue that the 1.0 webpage will return false, as if it's out of date when the client would technically be ahead.

The "Content-Type" headers are not very necessary. It's more used to make it more viewable in a webpage (and technically more correct), because it sees it as a text document instead of an HTML page.

Alternatively, you can use string.gmatch and compare each version number individually. This works with strings like "1.0.1".

function isOutdated(current, remote)
    local cfunc = current:gmatch("%d+")
    local rfunc = remote:gmatch("%d+")
    local cnum = tonumber(cfunc())
    local rnum = tonumber(rfunc())
    while cnum and rnum do
        if cnum ~= rnum then
            return cnum < rnum
        end
        cnum = tonumber(cfunc())
        rnum = tonumber(rfunc())
    end
    return rnum ~= nil
end



#268808 to find out how to get informations about a pixel

Posted by The Crazy Phoenix on 05 August 2017 - 08:06 PM in Ask a Pro

If it did exist, it would be in the term API.



#268774 PIM Help

Posted by The Crazy Phoenix on 03 August 2017 - 09:22 AM in Ask a Pro

View PostXeroTR, on 02 August 2017 - 09:28 PM, said:

Ok, This has been resolved, I'm just stupid and found the really easy answer.

It's best to leave the original post and add a reply describing the solution in case anyone else has the same issue and comes across this thread.



#268733 Corrupt-A-Wish!

Posted by The Crazy Phoenix on 01 August 2017 - 09:42 AM in Forum Games

Granted. The universe is now a mess because the first law of thermodynamics no longer applies.

I wish things were more durable.



#268726 Corrupt-A-Wish!

Posted by The Crazy Phoenix on 01 August 2017 - 01:35 AM in Forum Games

Granted, unfortunately spacetime broke so nothing has changed.

I wish EveryOS' wish hadn't prevented me from wishing (didn't want the thread to die) so that Dave-ee Jones wouldn't have wished for me to have wished.



#268725 java.lang.ArrayIndexOutOfBoundsException

Posted by The Crazy Phoenix on 01 August 2017 - 01:32 AM in Ask a Pro

Although Bomb Bloke's "while true do" solution is the best, there are a few unmentioned details about the call stack.
Namely, if the called function's output is returned in the current function (i.e. "return func()"), the called function will replace the current function in the stack instead of being added to it.



#268720 litPix - Little Pixels without Limits [v0.8]

Posted by The Crazy Phoenix on 31 July 2017 - 11:48 PM in APIs and Utilities

View PostPixelFox1, on 31 July 2017 - 11:30 PM, said:

View PostThe Crazy Phoenix, on 24 July 2017 - 03:41 PM, said:

You can use "term.getSize" to get the size of the display. That will allow your program to work correctly on customized computers, pocket computers and monitors.

And you think I don't know that?

I was pointing it out because you hard-coded the screen dimensions into your API.



#268719 read() persisting after parallel waitForAny returned a different function

Posted by The Crazy Phoenix on 31 July 2017 - 11:45 PM in Ask a Pro

Instead of using coroutines, try changing the os.pullEvent function to implement the behaviour you seek.

local killed = false
local oldPullEvent = os.pullEvent

function os.pullEvent(filter)
	while true do
		local event, r1, r2, r3, r4, r5 = os.pullEvent()
		--# In place of this comment, check if the event would trigger the custom behaviour and, if so, set killed = true and return an enter key event.
		if not filter or event == filter then
			return event, r1, r2, r3, r4, r5
		end
	end
end

local input = read()
if killed then
    --# Custom behaviour
else
    --# Enter pressed by the user
end
os.pullEvent = oldPullEvent

There are different ways of editing os.pullEvent to cause the behaviour you want. This is only one way of doing it.



#268712 Corrupt-A-Wish!

Posted by The Crazy Phoenix on 31 July 2017 - 05:39 PM in Forum Games

Granted. Unfortunately, that person has no wish.

I wish this could be a wish.



#268704 rednet:87: Expected number

Posted by The Crazy Phoenix on 31 July 2017 - 11:49 AM in Ask a Pro

View PostFeolthanos, on 31 July 2017 - 11:00 AM, said:

Well, the file transfer works for now, but there's a little something that I want to solve. My user creation program saves all the files with a user number (user#01 etc.) but can I make it so that it keeps track of how many users it has created and automatically saves it with a higher value ID (user#002 etc.) ?

You could create a file that tracks the number, but that'd mean that the program breaks if you tamper with the save data.
Instead, try using fs.complete("user#", dir) and then using the length operator to count how many files start with "user#".
Then, to make sure, verify that the next index exists, and as long as it doesn't, keep incrementing.
In other words...

    local files = fs.complete("user#", dir)
    local index = #files + 1
    while (fs.exists("user#"..index)) do
        index = index + 1
    end



#268698 Opus OS

Posted by The Crazy Phoenix on 31 July 2017 - 01:54 AM in Operating Systems

View PostHomedog, on 30 July 2017 - 07:32 PM, said:

View PostKepler, on 06 November 2016 - 06:27 AM, said:

Controlling multiple turtles
Spoiler

I am quite the noob to computercraft and I gotta know how you got that turtle set up.

The turtles track their current position and facing as they move around (by checking whether the movement succeeded).
This information can be used for dynamic GPS hosts (which may be what's used for the "follow" command), as well as instructing the turtle where to go.
All it takes at setup is to feed the turtle its coordinates (manually or through GPS) and facing (manually or by moving the turtle and using GPS again).