On, GitHub for ClrMd, I read
// If we just happen to have the correct dac file installed on the machine,
// the "TryGetDacLocation" function will return its location on disk:
string dacLocation = version.TryGetDacLocation();
I have added ClrMd via NuGet. In the properties it says Microsoft.Diagnostics.Runtime version 0.8.31.1 and that method is not available on the ClrVersion object.
class Program
{
static void Main(string[] args)
{
var dump = DataTarget.LoadCrashDump(args[0]);
dump.SymbolLocator.SymbolPath = #"srv*d:\debug\symbols\*https://msdl.microsoft.com/download/symbols";
// TODO: Hack. We assume that there's at least one runtime.
ClrInfo clrVersion = dump.ClrVersions[0];
}
}
I have seen this question which states that the method was removed - but what do I do instead?
The LocalMatchingDac property of the ClrInfo instance will give you the DAC location.
class Program
{
static void Main(string[] args)
{
var dump = DataTarget.LoadCrashDump(args[0]);
dump.SymbolLocator.SymbolPath = #"srv*d:\debug\symbols\*https://msdl.microsoft.com/download/symbols";
// TODO: Hack. We assume that there's at least one runtime.
ClrInfo clrVersion = dump.ClrVersions[0];
// Get the DAC location
string dacLocation = clrVersion.LocalMatchingDac;
}
}
HTH
Doug
Related
Okay so I am making a custom feature for my OP-Prison server, one of the things that I need to do is get an integer from the players.yml file, check if it is >= one, if it is take away one, save it and then if it is still above one then they can repeat the action untill it's 0.
The issue comes with the fact that I have to restart the server for the file to change, and even when I do, it will only go down by one integer at a time, before having to reload it again.
GUI Creation code:
Main main = Main.getPlugin(Main.class);
#SuppressWarnings("unused")
private FileControl fc;
#SuppressWarnings("unused")
private FileControl playerfc;
public static String inventoryname = Utils.chat(Main.pl.getFileControl().getConfig().getString("Backpacks.White.InventoryName"));
public List<Player> WhiteOpened = new ArrayList<>();
public static Inventory whiteBackpack(Player player) {
Inventory whiteBackpack = Bukkit.createInventory(null, 27, (inventoryname));
UUID uuid = player.getUniqueId();
whiteBackpack.setItem(10,
new ItemCreator(Material.INK_SACK).setData(8)
.setDisplayname(Utils.chat("&fCommon Packages &8ยป &f&l" + Main.pl.getPlayerFile().getConfig().getInt("Users." + uuid + ".Packages.Common")))
.getItem());
return whiteBackpack;
}
Code for updating the config + item when the Commonpackage is clicked:
#EventHandler
public void whiteBackpackInteract(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
UUID uuid = player.getUniqueId();
ItemStack clicked = event.getCurrentItem();
String title = event.getInventory().getName();
if (title.equals(inventoryname)) {
// Making it so that the item cannot be moved
event.setCancelled(true);
if (clicked != null) {
if (event.getSlot() == 10) {
// Getting the user's common packages section in the config and checking if it is greater than or equal to 1.
if (Main.pl.getPlayerFile().getConfig().getInt("Users." + uuid + ".Packages.Common") >= 1) {
// Saving the user's common package section to 'currentCommon'
Integer currentCommon = Main.pl.getPlayerFile().getConfig().getInt("Users." + uuid + ".Packages.Common");
// Taking away one from 'currentCommon' and saving it to 'newCommon'
Integer newCommon = currentCommon - 1;
// Getting the 'players.yml' file
File file = new File(main.getDataFolder(), "players.yml");
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
// Checking if the current common keys is greater than or equal to 1
if (currentCommon >= 1) {
try {
//Now, Here's where the error lies.
//Gets the player's common package count and sets it to the 'newCommon' count
config.set("Users." + uuid + ".Packages.Common", newCommon);
//Saves the players.yml file
config.save(file);
} catch (IOException e) {
e.printStackTrace();
}
// Updates the inventory they're currently in (Atleast it's meant to...)
player.updateInventory();
// Sends them a message (This is just for testing purposes, making sure it's working.)
player.sendMessage(Utils.chat("&8(&9Vexil&8) &fCommon Package"));
}
}
}
}
}
}
If there is any other code that you need, just ask I'll happily provide it for you.
Right now, you need to restart the server for it to save the data to the file. This should not happen, since you are calling the method config.save(file). The following is simply speculation, but it's the only cause that I think can easily explain what is going on.
In the object that is returned by getPlayerFile().getConfig(), there is likely a variable that stores a FileConfiguration object. That variable houses all the data from the players.yml file. In your whiteBackpackInteract() method, you load the data all over again. You then continue on to write to this NEW FileConfiguration variable, rather than the one that is stored in getPlayerfile().getConfig(). Since you then proceed to save to the file directly, the variables stored in the getPlayerfile().getConfig() is never told that you changed some values around. To fix this, you need to change the following:
config.set("Users." + uuid + ".Packages.Common", newCommon);
config.save(file);
to this:
Main.pl.getPlayerFile().getConfig().set("Users." + uuid + ".Packages.Common", newCommon);
Main.pl.getPlayerFile().getConfig().save(file);
and then delete this line of code:
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
This should solve your problem entirely. If it does not, I would recommend not using your friend's custom config API and instead just use the ones that are built in. Using third party code that you don't properly understand can very often lead to problems such as this.
The following are not the bugs, but are suggestions to help improve your code:
You should be sure to put your comments ABOVE or to the RIGHT over the code they describe. People read from top to bottom, so the comments (before I made the suggested edit to your post) were all below the code they describe.
Typically, you want to try to make sure that if code doesn't need to be run, it isn't. Since the int newCommon is not used until inside that if statement, you should move it in there.
You are using Main.getPlugin();
Now while that doesn't seem like such a bad thing, your getting an unassigned variable, I have no idea how it is working but you're assigning Main to Main. There are 2 proper ways to actually get the main class.
The first, and generally best way, is to use dependency injection.
So basically,
public class Main extends JavaPlugin {
#Override
public void onEnable() {
BackpackListener listener new Backpacklistener(this);
getServer().getPluginManager().registerEvents(listener, this);
}
}
public class BackpackListener implements Listener {
private Main instance;
private BackpackUtil util;
public BackpackListener(Main instance) {
this.instance = instance;
util = new BackpackUtil();
}
#EventHandler
public void onClick(InventoryClickEvent event) {
//code
util.whiteBackpack(instance);
}
public class BackpackUtil {
public Inventory whiteBackpack(Main instance) {
FileConfiguration config = instance.getConfig();
//Do things
instance.saveConfig();
}
}
The next way you can do it is less optimal, and frowned upon, but still an easier option.
public class Main() {
public static Main instance;
#Override
public void onEnable() {
instance = this;
}
}
public class ConfigHelper() {
Main instance = Main.instance;
FileConfiguration config = instance.getConfig();
//Do things
instance.saveConfig();
}
It's good to get out of the habit of using the second method (It's called a singleton), because normally the main class will change, or have multiple instances, etc... but with Spigot there can only be one main instance and one thread.
I'm trying to build a command processor that can take any command that implements a marker interface (or maybe descends from a base class). The processor will handle the command that it is asked to process. However I'm struggling with resolving the true generic type as Resolve(Type) returns an object.
I'm not sure is how to cast this if at all possible?
public void Process(ICommand command)
{
var c = command.GetType();
var t = typeof(ICommandHandler<>).MakeGenericType(new[] { c });
var o = container.Resolve(t);
//((ICommandHandler)o).Handle(command); *** This doesn't work
}
The calling code would be something like this -
Dispatcher.Process(new SomeCommand(Guid.NewGuid(),"Param1",12345));
If you absolutely have to call the ICommandHandler<T>.Handle method and you have no other control over the design of the system, then reflection may be your only choice. There's no great way to deal with the switch from generic to non-generic.
Otherwise, you may have a couple of options.
First, if your Dispatcher.Process can be made generic, you can save all the casting.
public static class Dispatcher
{
public static void Process<T>(T command) where T : ICommand
{
var handler = container.Resolve<ICommandHandler<T>>();
handler.Handle(command);
}
}
This is a pretty common solution to a problem like this that I've seen out in the wild.
If you can't do that, then you may be able to make your ICommandHandler<T> interface implement a non-generic ICommandHandler base interface.
public interface ICommandHandler
{
void Handle(ICommand command);
}
public interface ICommandHandler<T> : ICommandHandler
{
void Handle(T command);
}
In this latter case you'd have to switch your strongly-typed command handler implementations to call the same internal logic for generic or basic handling or you'll get different handling based on the call, which would be bad:
public class SomeCommandHandler : ICommandHandler<SomeCommand>
{
public void Handle(ICommand command)
{
var castCommand = command as SomeCommand;
if(castCommand == null)
{
throw new NotSupportedException("Wrong command type.");
}
// Hand off to the strongly-typed version.
this.Handle(castCommand);
}
public void Handle(SomeCommand command)
{
// Here's the actual handling logic.
}
}
Then when you resolve the strongly-typed ICommandHandler<T> your cast down to ICommandHandler (as shown in your question's sample code) will work.
This is also a pretty common solution, but I've seen it more in systems that existed before generics were available where an updated API was being added.
However, in all cases here, the problem really isn't that Autofac is returning an object; it's a class/type design problem that affects any generic-to-non-generic conversion scenario.
Using Reflection - but is this the best way to approach this?
public void Process(Command command)
{
var c = command.GetType();
var ot = typeof(ICommandHandler<>);
var type = ot.MakeGenericType(new[] { c });
var mi = type.GetMethod("Handle");
var o = container.Resolve(type);
mi.Invoke(o, new object[] { command });
}
Thanks in advance for your assistance. I have the following exported part:
[Export (typeof(INewComponent))] // orignally tried just [Export} here and importing NewComponent below
public class NewComponent : INewComponent
{
// does stuff including an import
}
The Console test program imports the above:
public class Program
{
[Import] // have tried variations on importing "NewComponent NewComponent" etc
public INewComponent NewComponent
{
get;
set;
}
public static void Main(string[] args)
{
var p = new Program();
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(p);
}
The Composition fails with these CompositionExceptions (I removed the namespace to protect the guilty :)):
1) No valid exports were found that match the constraint
'((exportDefinition.ContractName == "INewComponent") AndAlso
(exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso
"INewComponent".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))',
invalid exports may have been rejected.
The Composition works successfully if I do the composition in the main program like this:
public class Program
{
public static void Main(string[] args)
{
INewComponent newComponent = new NewComponent();
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(newComponent);
}
}
Thank You
Is your Exported part contained in the same Assembly as Program? If it is in a separate DLL, you need to include that Assembly in your catalog as well, like this:
var aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
aggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(NewComponent).Assembly));
var container = new CompositionContainer(aggregateCatalog);
// etc...
If that's doesn't work, then there is a nice open source tool called Visual MEFx that can help you analyze your catalog. Here is a short article about setting it up:
Getting Started With Visual MEFx
In your NewComponent class you wrote this:
// does stuff including an import
If there is a problem with that unshown import, then MEF will complain about the Program.NewComponent import instead of the actual deeper cause. This is called "stable composition". Stable composition can be useful, but it also complicates the debugging of a failed composition.
You can follow the instructions in the MEF documentation about Diagnosing Composition Errors to home in on the actual cause.
In a small program, you can also try to call container.GetExportedValue<ISomeExport>() for a few exports until you find the one that is causing problems.
when using Enyim memcached client to store data with a expire timespan, i find that it doesn't work.
Could anyone help?
In my test code, I store the date with 10 minutes expiration time, and i try to get it from cache immediately but got a null object.
Enyim.Caching.MemcachedClient client = new Enyim.Caching.MemcachedClient();
client.Store(Enyim.Caching.Memcached.StoreMode.Set, "one", 1, new TimeSpan(0, 10, 0));
object obj;
client.TryGet("one", out obj); // obj == null
Assert.AreNotEqual(null, obj); // this will fail
I'm not sure if you're being vague w/ your example or if you really are using an object type but I had the same problem using custom objects. Integers, strings, etc. would work fine but my custom object was always NULL as soon as I put it in the cache. Turns out I didn't have the Serializable attribute on my object. Once I put that on there everything worked as expected.
Hyacinthus is pretty precise on his question, the answers are somewhat irrelevant. I am having the same problem ONLY when setting an expiration, either as a Timespan or as a DateTime.
There is also an issue for this at Enyim's github https://github.com/enyim/EnyimMemcached/issues/110
We have a tweaked version at my company's codebase, but it is outdated. I will try to locate the fix and get back to this, and send a pull request to Enyim, when I find the time.
EDIT:
I also found this on github.
I can confirm that this was not happening with other build of the memcached server. I think it's a bug with this particular build:
Build with this issue:
http://www.urielkatz.com/archive/detail/memcached-64-bit-windows
Build WITHOUT this issue:
http://blog.elijaa.org/index.php?post/2010/08/25/Memcached-1.4.5-for-Windows
Care to check the server version you are using?
My initial comment still stands, as I run tests using the two different dlls, and the tweaked one works while the one shipped with CouchBase fails
Please check your server.
1.Use MemCacheD Manager
Or
2.Use telnet 127.0.0.1 11211(change to your sever setting)
and type:stats
It would show your the stats.
See the "time" item stat.
It's second format you must convert it,
Simply you can compare with "1262517674",
If smaller than "1262517674",your memcached server it too old.
Please Upgrade Or change your memcached version.
Otherwise Just change your memcached version
The answer is that memcached(windows) 1.4.4 64-bit version has this bug. If it fits your needs you can try 1.4.4 32-bit version for windows, or you can try to find another 64-bit compiled version. This problem also took my whole day and I finally installed "1.4.4 32-bit version" and viola, everything works perfect with 1.4.4. 32-bit.
Create a memcached client object is a costly operation, so try to create it on start of the application and reuse that object.
This how I initiate MemcachedClient Object and access Membese Build using Enyim client.
public class MemcachedManager
{
protected static MemcachedClient mc = null;
public MemcachedManager()
{
if (mc == null) initMemCached();
}
private void initMemCached()
{
MemcachedClientConfiguration config = new MemcachedClientConfiguration();
string ipstr = "192.168.1.1;192.168.1.2"; // List of Memcaced nodes
string[] ips = ipstr.Split(';');
foreach (string ip in ips)
{
config.Servers.Add(new IPEndPoint(IPAddress.Parse(ip), 11211));
}
config.Protocol = MemcachedProtocol.Binary;
mc = new MemcachedClient(config);
}
public void setWithTimeOut(string key, string value, int minutes)
{
mc.Store(Enyim.Caching.Memcached.StoreMode.Set, key, value, TimeSpan.FromMinutes(minutes));
}
public string getString(string key)
{
return (string)mc.Get(key);
}
public void setString(string key, string value)
{
mc.Store(Enyim.Caching.Memcached.StoreMode.Set, key, value);
}
}
you need to get a sington first.
eg:
using System;
using Enyim.Caching;
using Enyim.Caching.Memcached;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
MemcachedClient client = MemcachedManager.Instance;//new MemcachedClient();
client.Store(StoreMode.Set, "b", "bb", new TimeSpan(1, 1, 300));
var x = client.Get("b");
client.Store(StoreMode.Set, "a", "aa");
var y = client.Get("a");
client.Store(StoreMode.Set, "c", "cc", DateTime.Now.AddSeconds(300));
var z = client.Get("c");
client.Store(StoreMode.Set, "c", "ccc");
var t = client.Get("c");
Console.WriteLine("{0},{1},{2}",x,y,z);
}
}
public static class MemcachedManager
{
private readonly static MemcachedClient _instance;
static MemcachedManager()
{
_instance = new MemcachedClient();
}
public static MemcachedClient Instance { get { return _instance; } }
}
}
So have spent some time, and have decided to make a small game as a sideproject while I'm in school.
I'd like to make a command line game, perhaps some kind of rpg or mud.
My question is, what do I need to make this a reality?
I've looked at ncurses, and have been reading some documentation, is this a necessary step, or is there something easier? Are there any other particular technologies I will need compared to a regular command line application I might make it school?
Thanks.
You need two things:
A game engine
An interface
This is the exact same thing you need for a GUI game. The only only ONLY differences are your input and output mechanism.
So, write your game engine, make sure it's adaptable, and then your command line interface to control that engine.
========= Edit in regards to comments: =========
The goal of any interface is to map user requests to engine requests. Without knowing what language you're in, the specifics are going to be a bit... well ... nonspecific.
I can tell you how I would do it in Java.
I would create a UserRequest class with the following basic characteristics:
abstract class UserRequest {
protected GameEngine engine;
protected String command;
protected int numArgs;
public UserRequest(GameEngine engine) {
this.engine = engine;
this.command= command;
this.numArgs= numArgs;
}
public abstract void callback(User user, String[] args);
protected void checkArgs(String[] args) {
if(args == null || args.length != numArgs) {
throw new IllegalArgumentException("your args suck...");
}
if(!args[0].equals(command)) throw new IllegalArgumentException("commands don't match");
}
}
In my interface, I would have a Map<String,UserRequest> that is populated like this:
Map<String,UserRequest> behaviors = new HashMap<String,UserRequest>();
behaviors.add("MOVE",new UserRequest(engine,"MOVE",2) {
// define the engine callback
public void callback(User user, String[] args) {
// assume args[0] is command
int x = Integer.parseInt(args[1]);
int y = Integer.parseInt(args[2]);
engine.move(user,x,y);
}
}
public void repl() {
while(true) {
// assume you have a form of input - scanner perhaps?
String inputline = acquireNextInputLine();
String[] tokens = inputline.split("\\s"); // default split on white space
UserRequest behavior = behavior.get(tokens[0]);
if(tokens == null) displayError(inputLine);
try { behavior.callback(currentUser,tokens); }
catch(Exception e) displayError(e); // assume you have better error reporting than this!
}
}