241
Bay 12 Games Forum
- April 06, 2024, 05:16:18 am
- Welcome, Guest
News:
March 6, 2024: Dwarf Fortress 50.12 has been released.
News: February 3, 2024: The February '24 Report is up.
News: February 4, 2021: Dwarf Fortress Talk #28 has been posted.
News: November 21, 2018: A new Threetoe story has been posted.
Forum Guidelines
Show Posts
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
242
Utilities and 3rd Party Applications / Re: PyLNP 0.4 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: September 07, 2014, 09:21:25 am »
Version 0.4 is now out, containing new features like support for version checking on DFFD, support for TwbT overrides during graphics pack installation,and allows PyLNP.json to be stored in the LNP folder (the old placement will still work, though, and will be used for binary builds). It also adds better error handling in various places, and fixes various bugs.
Also, starting with this version, graphics pack installation will always patch inits - the old method of overwriting is gone.
Additionally, some refactoring has been done on the GUI side to make the code cleaner, and hopefully a little easier to work with. More work still needs to be done in this part (and the main LNP functionality hasn't been worked over yet), but this seemed like a good time to get a build out.
Also, starting with this version, graphics pack installation will always patch inits - the old method of overwriting is gone.
Additionally, some refactoring has been done on the GUI side to make the code cleaner, and hopefully a little easier to work with. More work still needs to be done in this part (and the main LNP functionality hasn't been worked over yet), but this seemed like a good time to get a build out.
243
Utilities and 3rd Party Applications / Re: PyLNP 0.3 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 31, 2014, 01:20:29 pm »The problem is currently solved by means of a shell script (xdg-terminal) which tries to detect it based on the DE, but I'm very much intersted in a better solution. Unfortunately, the environment variable you propose is only set if the program is already running in a terminal, and I can't guarantee that - so this one won't do, I'm afraid.Code: [Select]${COLORTERM:-${TERM:-xterm}} -e foo
It's a good idea, though, and I will strongly consider incorporating it in the shell script for the cases where it IS already in a terminal... but that's a little further down the line.
244
Utilities and 3rd Party Applications / Re: PyLNP 0.3 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 30, 2014, 09:25:52 am »The current commit (fecc2afc9d1c) is breaking settings (and causing the launcher to fail to open) - opening the launcher and toggling weather, for example, leaves behind [FPS_CAP:], [G_FPS_CAP:], [VOLUME:], and possibly others in init.txt.
Should be fixed in the latest commit, c660577 (could have sworn I tested for this...)
245
DF Modding / Re: Dwarf Fortress localization patch
« on: August 29, 2014, 12:10:10 pm »â = ├óThe font likely needs to be swapped, but this particular set of characters also suggests you have saved your file as UTF-8, but the game and/or the utility doesn't handle that encoding correctly (I don't know which one.). It seems you need to save the file in the appropriate single-byte code page (which your editor will likely call something like Windows-1252, Latin1, or possibly ANSI).
ç = ├º
246
Utilities and 3rd Party Applications / Re: PyLNP 0.3 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 29, 2014, 05:59:42 am »The DFFD site doesn't block Python requests. After a bit of investigation, it comes down to the fact that in Python there's no User Agent specified by default. I don't have Nginx on the server specifically configured to deny requests with no User Agent specified, so I'm not sure why they're getting blocked.
It does send a default user agent string on Windows, which is what I've mostly been testing with. This is the HTTP request generated when I just use urlopen2 directly (the code currently in the repository), as shown by the Fiddler HTTP debugger:
Code: [Select]
GET http://dffd.wimbli.com/file_version.php?id=7622 HTTP/1.1
Accept-Encoding: identity
Host: dffd.wimbli.com
Connection: close
User-Agent: Python-urllib/2.7The resulting download returns HTTP error 403 (Forbidden), and this HTML (irrelevant layout bits cut out):
Code: [Select]
<!DOCTYPE html>
<head>
<title>Access denied | dffd.wimbli.com used CloudFlare to restrict access</title>
</head>
<body>
<h2 class="cf-subheadline" data-translate="error_desc">Access denied</h2>
<h2 data-translate="what_happened">What happened?</h2>
<p>The owner of this website (dffd.wimbli.com) has banned your access based on your browser's signature (16183275254b0a5a-ua48).</p>
</body>
</html>The workaround I've implemented (and just pushed) is precisely to send a custom user-agent string ("PyLNP"):
Code: [Select]
# HG changeset patch
# User Michael Madsen<michael@birdiesoft.dk>
# Date 1409132432 -7200
# Wed Aug 27 11:40:32 2014 +0200
# Node ID fecc2afc9d1c40d2fef2579e0e12857de451ec65
# Parent f1ca127f6a819e78699340630e10d8f6e85fbf72
Change user agent of update checks to PyLNP
diff -r f1ca127f6a81 -r fecc2afc9d1c lnp.py
--- a/lnp.py Wed Aug 27 02:13:12 2014 +0200
+++ b/lnp.py Wed Aug 27 11:40:32 2014 +0200
@@ -23,10 +23,10 @@
try: # Python 2
# pylint:disable=import-error
- from urllib2 import urlopen, URLError
+ from urllib2 import urlopen, URLError, Request
except ImportError: # Python 3
# pylint:disable=import-error, no-name-in-module
- from urllib.request import urlopen
+ from urllib.request import urlopen, Request
from urllib.error import URLError
BASEDIR = '.'
@@ -712,8 +712,10 @@
return
if self.userconfig['nextUpdate'] < time.time():
try:
- version_text = urlopen(
- self.config['updates']['checkURL']).read()
+ req = Request(
+ self.config['updates']['checkURL'],
+ headers={'User-Agent':'PyLNP'})
+ version_text = urlopen(req).read()
# Note: versionRegex must capture the version number in a group
new_version = re.search(
self.config['updates']['versionRegex'],
247
Utilities and 3rd Party Applications / Re: PyLNP 0.3 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 27, 2014, 04:20:34 am »I've filled out the folders and links menus easily enough, but I don't quite know where to start with the update section. Can it check this link?Currently, no, because DFFD blocks Python by default. It's possible to make Python disguise itself to slip through the block, but that isn't being done right now (the hope was that MagiX' work could be incorporated, but since he left it alone for the time being, it hasn't been).
I've added that now, though, so it'll be part of the next build, which will either go out very soon (today or tomorrow, to get a bug fix out of the pipeline), or after a round of refactoring (I don't know exactly when that will be ready, but I'm guessing near the end of the week, or some time next week).
An option in the meantime could be to do one of the following:
- After uploading a new version to DFFD, update a file (e.g. a copy of whatever DFFD gives you) in your GitHub, then use a direct link to the latest version of that file (click through to view it on GitHub, then click the Raw button for the link you need)
- Change your topic to include the full version number as a continuous string and link to that
There are other options, of course; the key is that as long as you have a URL to a page you have some amount of control over, it should be possible to get it working.
How does the downloadURL work - if it's the download page that's fine, but the actual download link changes and I don't know it in advance.It is used as the URL that is opened if the user wants to update, so that's entirely up to you. This is only a check; the act of downloading and unpacking is left to the user (and because of that, you can use a DFFD link, even now).
Regex (help!!)?Since I don't want to force a specific format on the file (a DFFD-only solution is not good enough IMO, and I don't know what everyone will be using outside of that), it is unfortunately necessary for the pack author to provide a regular expression which will capture the version number (and ONLY the version number) in a so-called capturing group (marked by parentheses "()").
Fortunately, this is a one-time thing (as long as the format of your file doesn't change, you never need to touch it after it's been set once), and I'm perfectly willing to help.
For DFFD's check_version.php script (and anything else that contains a Version line like that), this field should be "Version: (.+)" (without the quotes).
If you e.g. changed the title of your forum post to "Dwarf Fortress Starter Pack 40_10 r1", you could use "<title>Dwarf Fortress Starter Pack (.+?)</title>"; if you added a line that said the same as DFFD's script, you should use "Version: ([^<]+)" (make sure there's an actual line break after it, though, so the HTML will contain a
tag). That last one would still work if you started out using the topic, and then switched to DFFD when it's available.
If you're doing something completely different, feel free to ask me. Alternatively, if you want to do it yourself (and learn regular expressions in the process), copy the entire contents of whatever URL you're using into http://www.regexr.com/ and work on it until you get something that does the job (it should highlight precisely one thing, and if you hover your mouse over that thing, it should show just the version number as being matched by the group). If you're linking to an HTML page, make sure you're working on the source code of the page; not whatever your webbrowsre renders.
Does or can the pack version autofill, or should I add that to my prep script?
You need to add it to your prep script. There's no attempt to parse the version number; it only checks if there's a difference between the one it sees online and the one in PyLNP.json.
248
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 24, 2014, 01:01:45 pm »If you can think of a good way to do that, I'd be very interested to hear it. So far, I don't see much potential for abstraction beyond adding tooltip and binding directly at construction time, and that would currently contribute such a small difference that I have not considered it worthwhile to do (at least, not yet).The general principle here is Don't Repeat Yourself (DRY). If you find yourself repeating small variations of the same pattern over and over again, you should consider making a function. The parts that vary will then become the parameters of that function. For a more detailed explanation: http://sourcemaking.com/refactoring/extract-method. IDE's like Eclipse make doing this a lot easier.
For example: In tkgui.py, many buttons are created in the same way: Create the button, assign a tooltip, configure the grid and register it with the controls dictionary. See the following snippet:Code: [Select]backup_saves = Button(
saverelated, text='Backup Saves',
command=lambda: self.cycle_option('autoBackup'))
create_tooltip(backup_saves, 'Makes a backup of every autosave')
backup_saves.grid(column=0, row=2, sticky="nsew")
self.controls['autoBackup'] = backup_saves
compress_saves = Button(
saverelated, text='Compress Saves',
command=lambda: self.cycle_option('compressSaves'))
create_tooltip(
compress_saves, 'Whether to compress the savegames '
'(keep this on unless you experience problems with your saves')
compress_saves.grid(column=1, row=2, sticky="nsew")
self.controls['compressSaves'] = compress_saves
This can easily be refactored into a function, eliminating the need of recoding the same button creation process over and over again:Code: [Select]def create_option_button(self, parent, row, column, key, text, tooltip):
button = Button(
parent, text=text,
command=lambda:self.cycle_option(key))
create_tooltip(button, tooltip)
button.grid(column=column, row=row, sticky="nsew")
self.controls[key] = buttonCode: [Select]self.create_option_button(saverelated, 2, 0, 'autoBackup', 'Backup Saves', 'Makes a backup of every autosave')Now, let's suppose you want to change the button to a checkbox. In stead of having to change a lot of your code, you can just change the create_option_button function (maybe rename it, which will be a simple search and replace) and be done with it.
self.create_option_button(saverelated, 2, 1, 'compressSaves', 'Compress Saves',
'Whether to compress the savegames '
'(keep this on unless you experience problems with your saves')
Sure, but that's the easy part

The part that's difficult is the layout. Just a column/row isn't enough; sometimes I need to use .pack instead of .grid; sometimes I need the button to span two columns... I've been trying to come up with an elegant solution to *that*, without too much luck.
Having said that, some ideas have come to mind just a short while ago, and now that the issues list is cleared out and 0.3 is released, the next step will likely be to try some of those out (and other steps of refactoring, of course).
249
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 23, 2014, 05:26:00 pm »In terms of design, I spend a little time contemplating the various options I can come up with, and pick the one that makes most sense (keeping KISS in mind). That, for example, means that unless I have a good reason to split something into its own file or function, I don't. File length (or method count) is not a good reason in and of itself.Scientific studies show a strong correlation between, amongst others, large units (methods, funcions, etc) and modules (files, classes) and low defect resolution efficiency. Having few modules in your app doesn't make it simple, when those modules have many responsibilities. Having many modules in your app doesn't make it complex, when those modules are small and have a clear responsibility.
There are other factors in that problem, though, such as dependencies between objects. The vast majority of methods in lnp.py are really completely independent of each other (the object itself is little more than a data provider and common access point); they do not NEED to be part of the same object, but it is not obvious what the (actual, not theoretical) benefit would be if they were split.
There is no inherent difference (excluding syntax) between "self.lnp.install_graphics(...)" and e.g. "self.lnp.graphics.install(...)"; it takes the same amount of effort to use either one and it takes the same amount of effort to locate the method if you need to change it. There can be other reasons to prefer one over the other, of course, but I do not think it is obvious exactly where those reasons are significant enough.
That doesn't mean there aren't places where it makes sense to pull some functionality out to a new file/object (I'm sure there are), or that it shouldn't be done (I'm sure it should), or that the current design is the best possible design (I'm sure it isn't) - I'm just saying it's more complicated than "the file is too long, let's split it".
That was not the point I was trying to make - doing things right from the get go is certainly both possible and preferable, and I definitely try to do so whenever possible. However, as you also say, there is no silver bullet - "the right way" is not always obvious, or unique... or objective.QuoteIt is certainly true that since the initial version, there are pieces of code that have become eligible for splitting (especially in tkgui.py). However, my priority has been getting the code to a state where someone wants to use it.QuoteSure, but sometimes, trying to do things "the right way" leads to not getting anything done.You seem to be implying that there's a conflict of interests between making software usable in a reasonable amount of time and doing things "the right way". I'm not saying that there is only one way of doing things right in software development, hence the quotes. However, I'm strongly rejecting the notion that "doing things right" will ever prevent you from getting anything done. If you're not getting anything done, you're doing it wrong! In my experience, the opposite is true: Doing things right from the get go will make you go fast, no exceptions.
QuoteOnce we're past this initial push of feature requests (we're basically there once the DFHack stuff is done), there's plenty of opportunity to refactor and find a sensible design (both in terms of code and UI).There's always an opportunity. Nobody is imposing deadlines or anything like that.
There is always an opportunity to re-design, but it is not always meaningful to do so. Getting the product out there gives more opportunity for feedback, and by extension, a better overview of what the program needs to deal with.
Refactor the repeating patterns of creating controls to factory methods for each type of control you create.
If you can think of a good way to do that, I'd be very interested to hear it. So far, I don't see much potential for abstraction beyond adding tooltip and binding directly at construction time, and that would currently contribute such a small difference that I have not considered it worthwhile to do (at least, not yet).
QuoteI'm a professional developer too - I absolutely recognize the value of good design, and no, I would not consider PyLNP to be well-designed as a whole (parts of it, yes; all of it, no). It is good enough as a starting point, though (otherwise, I should not have been able to take a year-long break between the initial port and the past week of feature requests).
I'm well aware that I'm touching on a somewhat sensitive subject here, but I'm only trying to help by pointing out an opportunity for improvement. Thanks for not being all defensive about it.
It's cool - I totally get what you're saying, and I appreciate it. I'm just viewing things a little differently
250
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 23, 2014, 08:19:12 am »There is another aspect to this, which hasn't been discussed at all, which is the maintainability of the source code of a launcher. If we want to create a launcher that will have the potential to be the de facto standard for an extended period of time, the source code needs to be maintainable and be kept maintainable. For devs that want to contribute, it should be reasonably easy to figure out how the program works under the hood. That way, adding new functionality and modifying existing functionality should remain reasonably easy for a dev with a little bit of experience under his/her belt.
This is, in my humble opinion, where PyLNP already falls behind. With lnp.py (almost 800 lines of code) being the "brain" of the program, it's falling prey to the God Object antipattern. The code for the "dumb" view, tkgui.py, is already 1400 lines of code (which is huge for a single module), partly because the entire layout of the GUI has to be handcoded and partly because recurring patterns haven't been refactored into reusable functions. The way loading/changing/saving settings works is set up in a smart way (with all the dictionaries and stuff), but it's quite hard to figure out exactly how it works.
In terms of design, I spend a little time contemplating the various options I can come up with, and pick the one that makes most sense (keeping KISS in mind). That, for example, means that unless I have a good reason to split something into its own file or function, I don't. File length (or method count) is not a good reason in and of itself.
It is certainly true that since the initial version, there are pieces of code that have become eligible for splitting (especially in tkgui.py). However, my priority has been getting the code to a state where someone wants to use it. Once we're past this initial push of feature requests (we're basically there once the DFHack stuff is done), there's plenty of opportunity to refactor and find a sensible design (both in terms of code and UI).
If you have a (concrete) idea about how to do something differently, tell me (or just do it and submit a pull request). I'm open to questions about how something works (or why it's done that way). I'm open to suggestions. I'm open to other UIs, too; if you want to make a nice GUI in Qt or whatever and hook it up, I'll take it.
I don't mean to sound harsh or be offensive. It's just that in my 18-year-and-counting career of being a professional developer, I've seen stuff like this happen many times. The enthusiasm and motivation is great, but often stops us from slowing down and taking the time to do things "the right way (tm)".Sure, but sometimes, trying to do things "the right way" leads to not getting anything done.
I'm a professional developer too - I absolutely recognize the value of good design, and no, I would not consider PyLNP to be well-designed as a whole (parts of it, yes; all of it, no). It is good enough as a starting point, though (otherwise, I should not have been able to take a year-long break between the initial port and the past week of feature requests).
251
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 22, 2014, 09:01:13 am »About Tkinter: Why did you choose to use Tkinter? As far as I know it's based off of the ancient Tk toolkit. It's got quite a few nuts and bolts, but lacks useful things like for example a listbox with checkboxes, which is used in the starter pack for selecting the utilities you want to autostart. It also lacks (again, afaik) a good GUI editor, which makes it incredibly easy to create nice looking user interfaces.
About a week ago I started recreating a DF launcher in Python using PyQt4 (mainly for some Python and Qt practice) and ended up recreating a fully functional program with the first 2 tabs of the starter pack launcher. The GUI was created with Qt's Designer program, which makes creating UI's a breeze. Below I've included a screenshot. The window is fully resizable, everything scales nicely.Spoiler (click to show/hide)
Tkinter is part of a standard Python install (except on Linux because... reasons), so it minimizes dependencies, and it keeps the executables reasonably small. That was pretty much it.
I am perfectly aware that much better UIs are possible with other toolkits (wxPython, QT, etc.), and I am also aware that eventually, it would probably be a good idea to switch to one of those - which is why I keep all actual functionality in a separate class and just make the UI a dumb view which calls down to that. Tkinter simply seemed like the most "neutral" choice, but I'm not married to it or anything

QuoteThat's a very good idea, but I tried creating that file and running it with xdg-open:...I can't believe GNOME folks intentionally keep this as "it's not a bug, it's a feature" after all those years.Code: [Select]$ xdg-open test.desktop
Warning: unknown mime-type for "test.desktop" -- using "application/octet-stream"
Error: No "view" mailcap rules found for type "application/octet-stream"
Opening "test.desktop" with Text Editor (application/x-desktop)
Can you try putting dfhack.desktop in $HOME/.local/share/applications and then just run "xdg-open dfhack" ?
I can sense some incoming problems with this approach, like GNOME asking user "run, cancel, open, run in terminal" every time. Can you test it?
I moved the file to that directory, and xdg-open won't find it just by name. The same applies if I drop it directly into /usr/share/applications.
But it turns out that doesn't matter, because I tried double-clicking the file in the file manager, and got this
Quote
There was an error launching the application.
Details: Failed to execute child process "xterm" (No such file or directory)
Okay, maybe it's just an issue with that specific distribution (Mint 15/MATE). So I tried Fedora 20/MATE (which, you'll recall, also didn't supply xterm). Same issue.
Well, maybe it's been fixed. Let me go update my Arch/MATE VM and see what happens... nope, same problem.
...what is this i don't even (╯°□°)╯︵ ┻━┻
Other approach: check for xterm->gnome-terminal->konsole->lxterminal->mate-terminal and run dfhack inside first found. Which is what shell script you linked earlier does.
That basic approach is looking like the only remotely sane one (with the option to specify a fallback in PyLNP.user). And it's not very sane.
The executables I get with PyQt are 11.5 Mb on Windows, 14.4 Mb on MacOS and 22 Mb on Linux (which surprises me, actually). They are not small by any means, but IMO also not extremely large.
Is that with or without UPX compression? There might be something to gain there.
252
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 22, 2014, 06:30:18 am »You probably based those assumptions on data available on distrowatch.com or some other source, that pulls data from distrowatch. There is one big problem with that. Distrowatch collects user-agent strings from people who go to this site. At the same time distrowatch is dedicated to a bit more tech savvy linux users. Hence Mint being first on this list or Debian being 3rd ("Vanilla" Debian has quite low desktop market coverage). But for a desktop app like pylnp don't think about distribution, think about freedesktop.org standards.
To the best of my knowledge, Mint is the most popular distribution these days, and one of its core desktop environments is MATE - where xdg-terminal does not work out of the box, so already there, I would argue you're not covering "most people".
Well, let me rephrase that then: it is A popular distribution, and the same issue applies to all MATE users anyway.
EDIT: exec* is not an option because utilities need to be launched after DF - so it's necessary to find a way to launch DF as an entirely stand-alone process, with its own terminal window. For Windows, I can use the start command; on OS X, I can use open. I haven't been able to figure out a useful possibility on Linux; I don't see a way to make Python do it directly, and I haven't been able to detect which terminal program the user is using to launch a new one. If anyone knows something I don't, I'm all ears.Try this:
1. Create .desktop fileCode: [Select][Desktop Entry]3. subprocess.Popen(["xdg-open", "dfhack.desktop"])
Name=dfhack
Comment=Run Dwarf Fortress with dfhack
Exec=path/to/dfhack
Terminal=true
Type=Application
Categories=Game;
4. Let desktop environment deal with it.
That's a very good idea, but I tried creating that file and running it with xdg-open:
Code: [Select]
$ xdg-open test.desktop
Warning: unknown mime-type for "test.desktop" -- using "application/octet-stream"
Error: No "view" mailcap rules found for type "application/octet-stream"
Opening "test.desktop" with Text Editor (application/x-desktop)
And yes, I did try making the file executable, just in case - didn't work. It looks like this is a long-standing bug from the GNOME days...
py2exe supports python3
Yes, but py2exe does not work for single-file distribution of Tkinter apps, and therefore I do not consider it a useful option. Pyinstaller was the only option for this.
Also, I want to keep dependencies to the absolute minimum, and since Linux does not include Tkinter support by default, I still need Linux binaries.
253
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 22, 2014, 04:59:53 am »And I agree with your thinking that we shouldn't depend on a single service
That was the main point I was trying to make - I'm all for having this kind of functionality if it makes sense. I just think that it should not be *required*, that is, even if git is used as the primary update method, we should still have support for plain HTTP downloads, to handle add-ons/utilities that aren't in a git repository (for whatever reason).
I think going down the path of partial updates is a grave mistake. Full pack updates are great, and I like the DF devlog integration in the Manilla launcher, but please don't break packs by asking users to update parts - or worse doing it automatically.
Getting the files, unpacking them, dealing with dependencies, all are significant technical challenges. It's a lot of code and a huge commitment to maintenance down the track (which I can't make). It's also hostile to new users; there is simply no way that this is going to work consistently without the user knowing what's happening - and for the Starter Pack at least it's a core goal to just work without requiring anything of the user. Every time a new player has to do anything besides learn to play DF, many just give up.
Having the launcher do anything related to partial updates is an appallingly bad idea. I won't ever use it. I will recommend that other people don't use it. It just doesn't fit the goal of a Newb Pack at all.
I'm not trying to be grumpy, just save us from our own enthusiasm. Listen to the voice of experience before it's too late. Please.
Pack authors need final control - I completely agree there. However, final control is not mutually exclusive with component-wise download/updating - so long as the pack author controls this part too.
Take the example of your own starter pack: Sometimes you have multiple releases for a single DF version. Fetching only the updated parts could make sense, and for some (not all!) pack authors, the effort can be worth it, especially once we move out of the bugfix phase of DF development.
Another option is as a tool for the pack author: use it to gather the files for your next release, but leave out the extra information when distributing it.
Under no circumstance should this replace the simple option that's currently in place, and it should never be mandatory. Ever. Your Starter Pack should be able to keep it as simple as you'd like, and I will reject any addition that prevents this.
It is, however, my distinct impression that some pack authors (or users) would like to be able to deliver at least some updates more incrementally. Perhaps this becomes too complicated and bloated to include in the standard launcher, and if so, then it can simply live on as a distinct fork for the people who really want to do this, or it can be pulled out into its own tool. I do not yet know; I won't know until I see more code.
254
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 22, 2014, 03:01:18 am »Please check out my fork of pyLNP, after you made a backup!
I added a version check and a download feature.
Right now, it is still quite rough, i.e. works on python3 only, it updates everytime you start pyLNP (which might be a bit too much, but I can still change it later) and only uses commandline input/output. Please test it a bit (you can change the version number in the created packages.json in your LNP folder to test the download/extract) and let me know about feedback.
I've only looked the code for now, but I still have comments:
Like Peridexis said, be careful about 100% automatic updates from "original" sources, because you might lose compatibility with the currently installed DF version. If you want to do component-wise updating, there needs to be a step where the user selects which parts to actually update - and you would probably want to leave old versions in case the new one doesn't work right.
You need to keep everything as generic as possible - that includes version checking! Take a look at the code that's already there for an idea about how to deal with that. (You'll need a regex per version checking URL.)
on my todo are:I would talk to the DFFD admin sooner, not later. If he says no, then you won't be able to use the code as-is anyway.
- only update every x-hrs/days/whatever (specified by pyLNP.user ?)
- make it a more fault tolerant, i.e. no inet connection, extraction failed, no write access,...
- try to get the extract feature done for OSX... Need someone to test it afterwards
- implement LZMA support for python 3.3+
- Get it into the user interface
- Contact dffd admin and ask if it is ok that I have "fun" with their server and circumvent their limitations (python is not allowed)
- add python 2 support
Other suggestions?
I tend to think that handling most cases is good enough, so my logic would be:
- if someone wants to use DFHack on Linux, use xdg if that'll work.
- otherwise make them configure it in the config, and don't spend time trying to make the launcher smart enough to help much.
- if they can't do that, no dfhack through the launcher.
I think this would cover most people under the first point, and those not covered are probably able to finish setting that up themselves. And the worst cast is they have to start DF manually to play with DFHack - hardly a disaster.
To the best of my knowledge, Mint is the most popular distribution these days, and one of its core desktop environments is MATE - where xdg-terminal does not work out of the box, so already there, I would argue you're not covering "most people".
EDIT: exec* is not an option because utilities need to be launched after DF - so it's necessary to find a way to launch DF as an entirely stand-alone process, with its own terminal window. For Windows, I can use the start command; on OS X, I can use open. I haven't been able to figure out a useful possibility on Linux; I don't see a way to make Python do it directly, and I haven't been able to detect which terminal program the user is using to launch a new one. If anyone knows something I don't, I'm all ears.Is there a reason for this? I think some utilities (DT?) check for DF on startup, but I don't know of any that exit immediately if DF isn't running (and either way, there's no guarantee which will finish launching first). Admittedly, exec() won't work with DFHack if PyLNP is launched without a terminal window, so it's not a complete solution.
I could probably get away with doing it the other way around, but as you mentioned, that only helps for the case where there is a terminal window to begin with.
Also, if it *becomes* necessary to delay launching utilities, I'd need to go back to starting DF first anyway, putting us back at square one.
It's worth mentioning that the current default is to not close the launcher when launching DF, which doesn't cause any problems with DFHack (until the launcher is closed, that is).
The fundamental issue is that DFHack needs access to a terminal while running, and there's (apparently) no way to guarantee that. While the specific problem of spamming the terminal only happens if you close the launcher while DFHack is running, it's only a symptom of the deeper problem. When there's no terminal (e.g. when using a pre-built executable), DFHack outright refuses to launch then.
Did you check $TERM environmental variable?$TERM specifies terminal capabilities, it does not specify the terminal executable itself. For example, on my primary Linux VM (Mint 15/MATE), it gets set to xterm (which is not installed, and does not have an alias in path).
subprocess.Popen() in python - doesn't that launch external process? This should open terminal and keep it opened even if you close pyLNPIt spawns a process that will keep running when PyLNP is closed, yes, but it does not spawn a new terminal window, and DFHack breaks if it doesn't have a terminal window (or loses exclusive access to one).
python 2 and 3 - is there specific reason to keep pyLNP compatible with py2?Like Dricus said, the ability to build executables is one of them, but it also increases the likelihood that the user can use any existing Python installation.
255
Utilities and 3rd Party Applications / Re: PyLNP 0.2 - Cross-platform Lazy Newb Pack port with graphics pack patching
« on: August 21, 2014, 06:19:59 pm »After a lot of searching, it appears there are precisely 2 options to spawn a terminal with reasonable reliability:
- Bundle the xdg-terminal script and just run that on Linux, or
- Reimplement the xdg-terminal script in Python to avoid having another file in there
Remember how I said this? Yeah, turns out xdg-terminal doesn't work on MATE.
I could modify the script to add support for MATE - but there are a lot of desktop environments that aren't explicitly listed in the script, so any one of those could break it.
Maybe LXDE, GNOME, KDE, xfce, MATE and Cinnamon support is enough? Maybe I just need parity with xdg-open, which I'm already using (though not for anything as mission-critical)? I don't use Linux enough to have any idea about how widespread the others are, but without a way to spawn a new terminal, I can't launch dfhack on Linux at all - it crashes if there's no terminal, and freaks out if the terminal doesn't remain available throughout (meaning the launcher can't be closed).
So, four possibilities:
1) Require a specific terminal (xterm/rvxt/whatever) is installed
2) Take MagiX' idea of having the user set the terminal in the configuration file (I'm not sure how to make sure people will set it properly... maybe require one run to go through a terminal and have the user select the executable among the parent processes?)
3) Modify xdg-terminal and fix it everytime someone has a non-working desktop environment (THAT'LL be fun...)
4) Force the user to launch DF themselves if they want to use DFHack on Linux
I need to figure out the least terrible way of handling this, and I'm not sure which one that is...


