<kentonv>
do you ever make a typo, and then in your attempt to undo the typo, fail to put the cursor in the right place, thus making a new additional typo, and so on, until you are like six typos deep and have to very carefully unwind the stack?
<kentonv>
huh so other than the if-none-match: * thing no changes are needed to Sandstorm for CalDAV?
frigginglorious has quit [Quit: frigginglorious]
frigginglorious1 is now known as frigginglorious
<synchrone>
UA whitelisting. Tons of it.
<synchrone>
logging of blocked clients
<synchrone>
somewhat better error message when a request is forbidden due to UA not being in whitelist
<kentonv>
I guess I meant, I expected CalDAV to introduce some new HTTP methods or headers we'd need to handle, but if not, awesome
<synchrone>
works for me (C)
<kentonv>
I wonder if CardDAV would similarly work now
<zarvox>
Probably!
frigginglorious_ has joined #sandstorm
<synchrone>
there's no decent desktop client for it
<synchrone>
but a local infCloud, pointed at API endpoint also works locally
<synchrone>
(patched sandstorm proxy http basic check to allow all UAs)
<synchrone>
so now i'm gonna need to test it with various clients to see if it's stable
<kentonv>
I may be coming around to the idea that we can avoid the whitelist if we use randomized API endpoints... there are risks, but maybe they aren't too bad. Need to think more.
derf- has joined #sandstorm
<synchrone>
remember, API link will be copied over to mobile phones\tablets\desktop software preferences\etc
<synchrone>
maybe there could be some .well-known \ SRV records support on the base domain?
<synchrone>
RFC6764 style?
<synchrone>
ah, but it's designed with an app in mind
<synchrone>
not a grain
<kentonv>
well people already need to copy over a username and password... is also copying an endpoint URL that bad?
<zarvox>
can the username/password/endpoint all get crammed into one URL via a suitable offer template?
<zarvox>
slash can the mobile apps be configured by QR code containing the appropriate URL?
<zarvox>
I do kinda like the "generate QR code on desktop/laptop, scan with phone, good to go" workflow where available
<synchrone>
not yet
<synchrone>
too bothersome\no solid standard to implement
<synchrone>
i was thinking why not just QR-code the URL with username:password@host
<synchrone>
but nowadays tokens are way to go
<kentonv>
I do want to support QR codes, but given the lack of any existing standard, we'll have to create our own and update apps accordingly, in which case we may as well base it on bearer tokens instead of basic auth.
<synchrone>
and actually, sandstorm has a good angle to push this authentication\endpoint topic
<synchrone>
apps would use some IPC on devices to authenticate their requests or get tokens
<synchrone>
the way google accounts work, for example
<synchrone>
not just google but all credentials are uniformly collected in a separate app
<kentonv>
yes, I'd love to have a Sandstorm mobile app which basically acts as a client-side powerbox for other apps to make requests from
<kentonv>
so then you connect your Sandstorm app to your server once and going forward apps know where to find your server and how to obtain a token
<kentonv>
but that's a big project. :)
<zarvox>
:)
<synchrone>
not just from development point of view. concept & a published standard is important
<zarvox>
In the interim, if we made a QR code offer template renderer, we could make something that could be consumed by any mobile app that registers a URI handler
<synchrone>
the only thing could be put into that QR is the https:// URL, which means Basic auth, which is a boo-boo
<synchrone>
yeah, but we're talking about apps, and some standard way to authenticate
<kentonv>
I imagine that could encode into a QR code just fine
<synchrone>
you don't want to tell appmakers to implement yet another behavior which only sandstorm could use
<synchrone>
s/use/support
<kentonv>
if there's no real standard then we'll present our own.
<zarvox>
sure. For instance, for two-factor auth, Google Authenticator can consume a URL that looks like otpauth://totp/<name>?secret=<secret>&issuer=<issuer>
<synchrone>
which brings us back to a necessity of publishing an RFC
<zarvox>
But otpauth:// wasn't a published spec at the time. It was just a thing that Google Authenticator did.
<kentonv>
I believe that the best standards start out as working practice, then get formalized later.
<synchrone>
indeed
<kentonv>
if you try to invent something and spec it in advance before anyone is using it, you'll end up with a bad standard
<synchrone>
so a solid concept, workflow, etc is required first
<kentonv>
so I think we should invent something and do it, and maybe write an RFC later after it is working in the wild
<zarvox>
Anyway, I'm most excited about the things we can make work today, which will give us the experience needed to recommend best practices in the future. :)
<synchrone>
okay, thank you guys for a nice discussion. i'm going afk for a while
synchrone has quit [Ping timeout: 250 seconds]
donught has quit [Ping timeout: 248 seconds]
|jemc| has quit [Ping timeout: 245 seconds]
aldeka has quit [Remote host closed the connection]
ocdtrekkie has quit [Remote host closed the connection]
aldeka has joined #sandstorm
ocdtrekkie has joined #sandstorm
jadewang has quit [Remote host closed the connection]
<zarvox>
There's probably corner cases where things break down, but I imagine this would do a decent job for QR offer templates.
<kentonv>
third attempt at fixing race: success!
<kentonv>
(... probably)
<zarvox>
:D
frigginglorious_ has quit [Quit: frigginglorious_]
frigginglorious_ has joined #sandstorm
mnutt has joined #sandstorm
frigginglorious_ has quit [Quit: frigginglorious_]
frigginglorious_ has joined #sandstorm
<mnutt>
I started looking into the wildcard etag issue, fixed the error but notice that the If(-None)-Match headers weren't actually being sent. Looking up node-capnp union syntax, I came across https://github.com/kentonv/node-capnp/issues/24. Could that be related?
<mnutt>
(for a second I thought github's caching was messed up, coming across an issue created 8 months ago and then commented on 5 minutes ago by kentonv)
mnutt has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
raoulzecat has joined #sandstorm
<stratospark>
any idea when the rocketchat on app store (v0.14.0) will be updated to latest release (v0.17.0)?
<asheesh>
Howdy stratospark
mnutt has joined #sandstorm
<stratospark>
hey
<stratospark>
I just started using sandstorm today to set up a server for my housemates
<stratospark>
Rocketchat is great, but i'm running into some issues. I was trying to see if it could be solved by upgrading to the latest spk on their release page
<asheesh>
stratospark: Hey, awesome!
<asheesh>
Hmm! Do they have a more recent release they just haven't sent to the app market?
<stratospark>
their spk on that page is 0.17.0, but i'm having trouble uploading it to sandstorm
<stratospark>
I get:
<stratospark>
"Upload failed: 500 Internal Server Error
<stratospark>
Unpacking SPK failed; is it valid?
<stratospark>
"
<kentonv>
the SPK seems valid but it's signed with the wrong app key
<stratospark>
But then I click around to some other grains on sandstorm and the install screen shows up for v0.17.0. I'm able to start a new grain but it doesn't seem to progress far
<stratospark>
I see this error in the debug log: Exception in queued task: Error: [CustomOAuth: Options.serverURL is required and must be String]
<stratospark>
at CustomOAuth.configure (packages/rocketchat_custom-oauth/custom_oauth_server.coffee:28:21)
<stratospark>
at Object.RocketChat.models.Settings.find.observe.added (packages/rocketchat_github-enterprise/common.coffee:19:22)
<stratospark>
at [object Object].observeChangesCallbacks.added (packages/minimongo/observe.js:153:1)
<stratospark>
at Array.forEach (native)
<stratospark>
at packages/mongo/observe_multiplex.js:183:1
<stratospark>
at self.applyChange.added (packages/minimongo/observe.js:53:1)
<stratospark>
at Object.task (packages/mongo/observe_multiplex.js:177:1)
<stratospark>
at Function._.each._.forEach (packages/underscore/underscore.js:105:1)
<kentonv>
it appears to have no PGP signature, though
<stratospark>
at [object Object]._.extend._run (packages/meteor/fiber_helpers.js:147:1)
<stratospark>
at packages/meteor/fiber_helpers.js:125:1
<stratospark>
ufs: temp directory created at /tmp/ufs
<stratospark>
configuring push
<stratospark>
Using GridFS for Avatar storage
<asheesh>
Oh I see, you're saying it crashes on launch but it's not a Sandstorm crash. Got it.
<asheesh>
That is to say, Sandstorm successfully delivers a crashing app experience to you.
<asheesh>
I think the answer is, stratospark, they're waiting on someone to manually test this version before they upload it to the app market.
<stratospark>
ok, sounds good!
<asheesh>
Given that fact, they probably want a GitHub issue saying what you tried, and what you experienced. I think this particular issue they'll know how to fix quickly, and then they'd want e.g. you to test something new.
<asheesh>
If you're willing to do that with them, by Jove it would be probably the greatest thing for Sandstorm on Rocket.Chat this month so far.
<stratospark>
sure, I'll write one up
<asheesh>
In particular, if you decide to care about the project and repeatedly test things for them, that'd be huge, because they have a lot of excitement about Sandstorm but not enough Sandstorm testers at the moment.
<asheesh>
But of course if you don't have focused attention for that, just filing an issue with a report of this one issue would be very helpful to them I'm sure.
<stratospark>
on a related note, is it possible to migrate a grain's data to a development version of whatever app I might want to hack on?
<asheesh>
I have two answers for you.
<asheesh>
1. No.
digitalcircuit has quit [Ping timeout: 252 seconds]
<asheesh>
2. Yes, if you're willing to play games with a ZIP file.
<asheesh>
The specific games to play with a ZIP file are:
<asheesh>
- Download a "grain backup" of a grain created with a non-dev version;
<asheesh>
- Unzip it, and then edit the "app ID" to point to the dev version.
<stratospark>
for example, I could have a grain of the chat running on the app store's version. then have another grain with the development version of the chat with the same data
<asheesh>
- Zip it back up, then use "Restore backup" in Sandstorm to "Restore" this to the dev version.
<asheesh>
Exactly.
<asheesh>
You'll have to do this trick once per "app ID", and I think in the Rocket.Chat case their autobuilder makes a new app ID every time it builds the package.
<asheesh>
So that might get a little tiresome after a while.
<kentonv>
asheesh: by "edit the app ID" you of course mean "replace the metadata file with one from a backup of the desired target app"
<asheesh>
I can probably write you a little command line tool that does this though.
<asheesh>
kentonv: surely a hex editor is all that's required!!??! (I haven't done this either ever or in a while, I forget)
derf- has quit [Ping timeout: 240 seconds]
<stratospark>
ok this all sounds really good! I'll feel a lot better about running a sandstorm server for my housemates if I can also use development spks when necessary
digitalcircuit has joined #sandstorm
derf- has joined #sandstorm
<asheesh>
stratospark: Awesome.
<asheesh>
...but...
<asheesh>
keep in mind the grain ID will change if you do that.
<asheesh>
So it'll break people's existing links to the grain.
<asheesh>
If that's a problem, you can either monkey with the database (!) or ... something.
<asheesh>
BTW stratospark if you're based in the SF Bay area, or NYC, or Boston, or Europe, please consider joining a Sandstorm meetup: sandstorm.meetup.com
ocdtrekkie has quit [Remote host closed the connection]
aldeka has quit [Remote host closed the connection]
aldeka has joined #sandstorm
ocdtrekkie has joined #sandstorm
tobald has joined #sandstorm
stratospark has joined #sandstorm
stratospark has quit [Client Quit]
synchrone has quit [Ping timeout: 250 seconds]
synchrone has joined #sandstorm
stratospark has joined #sandstorm
<synchrone>
hmm, strange things happen to my SPK after i switched to python3
<synchrone>
in dev mode it works fine
<synchrone>
in vagrant-spk ssh it works fine
<synchrone>
after I package it - Fatal Python error: Py_Initialize: Unable to get the locale encoding
stratospark has quit [Client Quit]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 240 seconds]
xet7 has quit [Quit: Leaving]
stratospark has joined #sandstorm
stratospark has quit [Client Quit]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 245 seconds]
stratospark has joined #sandstorm
stratospark has quit [Client Quit]
ocdtrekkie has quit [Remote host closed the connection]
aldeka has quit [Remote host closed the connection]
mnutt has joined #sandstorm
frigginglorious has quit [Ping timeout: 256 seconds]
eternaleye has quit [Remote host closed the connection]
M-eternaleye has joined #sandstorm
ocdtrekkie has joined #sandstorm
aldeka has joined #sandstorm
jadewang has joined #sandstorm
frigginglorious has joined #sandstorm
jadewang has quit [Ping timeout: 264 seconds]
M-hrjet has joined #sandstorm
stratospark has joined #sandstorm
stratospark has quit [Client Quit]
aaronr has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 240 seconds]
stratospark has joined #sandstorm
stratospark has quit [Client Quit]
wolcen has joined #sandstorm
xet7 has joined #sandstorm
xet7 has quit [Client Quit]
xet7 has joined #sandstorm
tobald has quit [Quit: Ex-Chat]
|jemc| has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 240 seconds]
stratospark has joined #sandstorm
stratospark has quit [Client Quit]
stratospark has joined #sandstorm
stratospark has quit [Client Quit]
<synchrone>
Unusually quiet here today...
* asheesh
stretches
<synchrone>
oh, asheesh is here :)
<asheesh>
Good morning - I for one just woke up.
<synchrone>
good morning to you then
<asheesh>
synchrone: Yeah, I ran into the same issue at one point. I think it has to do with not enough stuff being in the 'spk dev' trace. But I forget what the root is. If you have a package that I can fiddle with, then I might try looking at that.
<asheesh>
Or I can try to making a Python 3 package from scratch.
<asheesh>
Do me a favor and make this be `alwaysInclude = [ "env", ],`
<asheesh>
If you do that, you'll repack with 100% of the virtualenv in there, which you definitely do want.
<asheesh>
Well basically definitely. Close enough to definitely.
<synchrone>
wha... but how did it work before
bb010g has quit [Quit: Connection closed for inactivity]
<synchrone>
if it wasn't included
<synchrone>
or did it rely on sandstorm-files.list ?
<asheesh>
It does rely on sandstorm-files.list.
<synchrone>
..which is somehow not always 100% populated ...
<asheesh>
The `env` path is resolved with regard to the "searchPath" entries, fwiw.
<asheesh>
For some reason that I don't understand, these files search multiple directories, which results in it being impossible to specify an absolute filsystem path, which is IMHO too bad.
<asheesh>
As with many things I don't understand, there could be a good reason.
<synchrone>
okay, will try with alwaysInclude
<asheesh>
That might not be enough. You might need to also alwaysInclude usr/lib/python3.5 for example.
<asheesh>
But you'll see/we'll see.
<asheesh>
In general, the reliance on sandstorm-files.list makes things shaky. I'd like to be able to distribute, like, sandstorm-files.list.d/python that makes Python stuff work more reliably, something like that.
jadewang has joined #sandstorm
<asheesh>
I'm going to focus for now on the immediate issue, since that's what I can do first.
<asheesh>
So let me know if adding 'env' helps.
<synchrone>
sure
<asheesh>
And in fact, that is probably Looks like 'encodings/__init__.py' in the virtualenv showing up will help you, but it might end up being a broken symlink until you also alwaysInclude the system Python dir.
* asheesh
has done some more Googling.
jadewang has quit [Ping timeout: 272 seconds]
synchrone has quit [Ping timeout: 264 seconds]
aldeka has quit [Remote host closed the connection]
ocdtrekkie has quit [Remote host closed the connection]
ocdtrekkie has joined #sandstorm
aldeka has joined #sandstorm
synchrone has joined #sandstorm
<synchrone>
hurr... local app spk uploading is somehow so slow ...
bb010g has joined #sandstorm
<asheesh>
Yeah, it's a vagrant networking issue, it seems.
<asheesh>
There are a bunch of knobs one can twiddle.
<asheesh>
What host OS? Mac OS?
<synchrone>
ubuntu
<asheesh>
FWIW if you end up finding the right collection of knobs to twiddle, then I can make them correctly pre-twiddled.
<asheesh>
Oh snap
<asheesh>
I'm on Debian, so presumably I'd have the same issues.
<synchrone>
didn't you notice it?
* synchrone
is using sandstorm-143btw
<asheesh>
Yeah, but it's been a while; I guess I work around it by doing uploads to oasis of my SPKs, nowadays.
<asheesh>
I probably filed a bug ages ago. Probably I should try harder to fix it.
<synchrone>
Request URL:http://local.sandstorm.io:6080/upload/AcLG9g6JFekKPAeWT took 6.4 min for 15897944 bytes
<asheesh>
Let me test if virtio-net helps, brb.
<synchrone>
also, packing opt/app/env didn't help. will try with usr/lib
<asheesh>
usr/lib/python{{versionNumber}} to be more efficient, if you're OK with that!
<asheesh>
You probably want env as well, fwiw.
<synchrone>
just specifying alwaysInclude = ["env"], triggers a complaint
<synchrone>
i had to use alwaysInclude = ["opt/app/env"],
<asheesh>
Ah, OK, cool.
<asheesh>
That is good, honestly.
<asheesh>
OK I can repro the slowness.
<asheesh>
Changing to virtio-net adapter type...
<asheesh>
OK virtio-net is a bajillion times faster.
<asheesh>
So now the question is, how/if I should integrate this into Vagrantfile.
<asheesh>
I could just make the default safe, and allow people to edit Vagrantfile to set this option.
<asheesh>
zarvox: y u use /usr/local/lib and not a virtualenv!!? (although with only one real Python app on the system, we could recommend against a virtualenv, but I think since most Python web app developers tend to use virtualenvs, probably smarter to go that way)
<asheesh>
+1 to the alwaysInclude
<dwrensha>
would it be possible for `vagrant-spk publish` to upload the spk from the host rather than the guest?
<asheesh>
I just ran into that on Monday with my little autotester for MediaGoblin, so this conversation is actually very much up my alley.
<asheesh>
dwrensha: Curious why that matters!
<dwrensha>
presumably it would be much faster
<asheesh>
Oh, I see.
<dwrensha>
is there some other case where fast networking is needed/
<dwrensha>
?
<asheesh>
Yeah, upload SPK to one's own dev instance
<kentonv>
does virtualbox still have weird random network slowness?
<dwrensha>
that's the place where I noticed it
<dwrensha>
maybe we need `spk install`?
<dwrensha>
I guess my workflow is to upload to a non-vagrant server when I want to do non-dev-mode testing
jadewang has quit [Remote host closed the connection]
synchrone has quit [Ping timeout: 240 seconds]
coyotebush has joined #sandstorm
rolig has joined #sandstorm
<zarvox>
asheesh: beacuse I have to use the system-wide capnproto that I compile from git sources, and then I have to pip install pycapnp to use that lib
<zarvox>
I think I ran into issues when trying to do this with a virtualenv
<asheesh>
Oh wowee.
<asheesh>
That's basically just because we haven't done a capnproto release, right?
<asheesh>
So many moving parts. Life is fascinating.
<zarvox>
dwrensha: can't upload from the host unless we compile native code for the host - IIRC the upload request signs a statement with the package key that is probably a capnproto struct, and to read/write that probably requires libcapnp, which basically requires native code
jadewang has joined #sandstorm
M-eternaleye has quit [Changing host]
M-eternaleye has joined #sandstorm
M-eternaleye is now known as eternaleye
notevil has joined #sandstorm
mnutt_ has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
funwhilelost has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
funwhilelost has joined #sandstorm
<asheesh>
OK I'm playing with double-installs. Trying to get a sense of why people would do that.
<asheesh>
If people have ever run install.sh twice, on the same machine, and are willing to tell me what you were really trying to do, that'd be super helpful!
<maurer>
asheesh: I have done so, twice.
<maurer>
asheesh: The first time was because I was trying to force downgrade a development version I had installed.
<maurer>
asheesh: The second time was to enable sandcats on a non-sandcats deployment
<asheesh>
Force downgrade. Fascinating.
<asheesh>
Because you had a custom Sandstorm build chosen?
<asheesh>
i.e. the output of 'make'?
<maurer>
Yes
<maurer>
I had a manually patched sandstorm to try something
<maurer>
and wanted to switch back to the official version
<kentonv>
FWIW "sandstorm update dev" will always install the latest release (from the dev channel, which is the only channel currently)
<kentonv>
(though probably the more-correct thing to do is update sandstorm.conf to specify dev as the channel, then do "sandstorm update")
<kentonv>
(otherwise it won't auto-update)
<maurer>
kentonv: OK, thanks
<kentonv>
I mean, I'm telling asheesh this so that someday re-running install.sh can offer to do it automatically. :)
<maurer>
Oh, on another subject, I read through the sandstorm email docs, and they all seem to assume that you want to send email from another domain
<maurer>
e.g. they use some other smtp server to send to
<kentonv>
1) I want to change the address of my server or switch to/from Sandcats. 2) I want to enable/disable automatic updates or change update channel. 3) I want to uninstall Sandstorm.
<maurer>
is this a permanent limitation, or just a temporary one b/c it's the more common setup?
<zarvox>
I "just" stop sandstorm, point the /opt/sandstorm/latest symlink at the older bundle in /opt/sandstorm, and start it again
<kentonv>
maurer: I'm not sure I understand the question.
<kentonv>
are you asking why Sandstorm doesn't act as a mail transport itself, but instead needs a separate SMTP server?
<kentonv>
I'm not sure what you mean about "send email from another domain"
<maurer>
kentonv: So, when you talk about Outgoing SMTP, you suggest sandstorm being given a SMTP Url to talk to
<zarvox>
maurer: most people haven't configured a mailserver and SPF and DKIM and DMARC
<zarvox>
but you can totally use smtp://localhost:25 if you have a local mail relay that will Do The Right Thing
<maurer>
kentonv: I'm wondering why it can't be the case that I essentially say "Sandstorm, I am maurer on this sandcats instance, can you make me a cap that lets me send and receive email as maurer@sandcats.io" ?
<maurer>
err, maurer@maurer.sandcats.io
<maurer>
but same idea
<kentonv>
I think there's multiple questions here
<maurer>
zarvox: Sure, but a large part of the point of sandstorm is to avoid having to do local server configuration
<maurer>
zarvox: _I_ can configure a mailserver, but it's a massive pain
<zarvox>
Agreed
<maurer>
zarvox: My less technically inclined friends can deploy sandstorm, but would fail if I told them to deploy postfix
<kentonv>
so, most users will need to use something like Sendgrid, Mailgun, or Mandrill to route email, because most ISPs as well as IaaS providers are widely blacklisted for spam
<maurer>
Hrm, I suppose that's true
<maurer>
(I forgot that I'm unique in having access to non-blacklisted IPs)
<kentonv>
at some point we want to offer an easy flow for setting up one of these
<maurer>
well, not literally unique, but uncommon
<kentonv>
probably Mailgun
<zarvox>
Also, reverse-DNS-matching-forward-DNS is one of the heuristics that folks use for determining authenticity of mail senders
<zarvox>
and we have no way to set up reverse DNS for users
<maurer>
zarvox: Is that a limitation of your deal with the sandcats dns provider?
<zarvox>
Within companies, I expect that most companies already have an internal mailserver/relay that Sandstorm could be pointed at.
<maurer>
zarvox: For companies, I agree that an SMTP Url is optimal
<zarvox>
maurer: no, that's a limitation of "we don't control what the sandcats user's ISP is/does"
<zarvox>
RDNS is handled by whoever owns the IP space
<kentonv>
maurer: your other question is about allocating email address capabilities. Yes, that's something we want to do eventually, as part of the "email driver", but it's a ways off
<maurer>
zarvox: Ooh yeah, I was only able to do that on my dns server because I was the dns and rdns delegate
<maurer>
zarvox: sorry, sometimes I forget things
<zarvox>
I also forget these things. I'm lucky to have a server with a stable IPv4 address that hasn't been blacklisted.
<maurer>
kentonv: Yeah, I suppose mailgun could be fine, since 10k/mo free is probably more than enough for a personal deployment
<maurer>
(as long as things were sufficiently streamlined)
<kentonv>
yeah, we'd want to automate the DNS setup too
jadewang has quit [Remote host closed the connection]
mnutt_ has joined #sandstorm
aaronr has quit [Ping timeout: 250 seconds]
bb010g has quit [Quit: Connection closed for inactivity]
funwhilelost has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
mnutt_ has quit [Quit: My Mac has gone to sleep. ZZZzzz…]
jadewang has joined #sandstorm
aaronr has joined #sandstorm
frigginglorious has quit [Quit: frigginglorious]
frigginglorious has joined #sandstorm
funwhilelost has joined #sandstorm
jadewang has quit [Remote host closed the connection]