I have a keyboard hook in order to receive data from the HID interface. It works, however, sometimes, a binary data is received causing windows to behave incorrectly.
This is the hook delegate:
private IntPtr KeyboardHookDelegate(
int nCode, IntPtr wParam, IntPtr lParam)
{
EventHandler<KeyboardEventArgs> handlerKeyPressed = KeyBoardKeyPressed;
EventHandler<DataEventArgs> handlerData = KeyBoardDataPresent;
if (handlerKeyPressed != null || handlerData != null)
{
_shiftPressed = KbdNativeMethods.GetAsyncKeyState(KbdNativeMethods.VirtualKeyStates.VK_SHIFT) < 0;
_capsLockOn = KbdNativeMethods.GetAsyncKeyState(KbdNativeMethods.VirtualKeyStates.VK_CAPITAL) < 0;
if (nCode == KbdNativeMethods.HC_ACTION)
{
KbdNativeMethods.KBDLLHOOKSTRUCT kbd = (KbdNativeMethods.KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KbdNativeMethods.KBDLLHOOKSTRUCT));
if ((wParam == (IntPtr)KbdNativeMethods.WM_SYSKEYDOWN) || (wParam == (IntPtr)KbdNativeMethods.WM_KEYDOWN))
{
if (kbd.vkCode == (uint)KbdNativeMethods.VirtualKeyStates.VK_LSHIFT || kbd.vkCode == (uint)KbdNativeMethods.VirtualKeyStates.VK_RSHIFT)
_shiftPressed = true;
else if (kbd.vkCode == (uint)KbdNativeMethods.VirtualKeyStates.VK_CAPITAL)
_capsLockOn = true;
else
{
char charPressed = GetCharFromKey(kbd.vkCode, _shiftPressed ^ _capsLockOn, false);
var isPrintable = (int)charPressed <= 0x7F && (!char.IsControl(charPressed) || char.IsWhiteSpace(charPressed));
if (isPrintable)
{
//Console.Write(string.Format("0x{0:X2} , ", (int)charPressed));
//if (charPressed != '\r')
// Console.Write(charPressed);
// Registra la última hora en que recibió un dato. Si ha pasado más de 3 segundos, debe limpiar el buffer.
DateTime newLastInput = GetLastInputTime();
if ((newLastInput - _lastInputTime).TotalSeconds >= 3)
_data.Clear();
_lastInputTime = newLastInput;
handlerKeyPressed?.Invoke(this, new KeyboardEventArgs() { Key = charPressed });
if (handlerData != null)
{
if (_data.Length > 500)
_data.Clear();
_data.Append(charPressed);
string tmp = _data.ToString();
if (tmp.StartsWith(_prefijo) && tmp.EndsWith(_sufijo))
{
_data.Clear();
string pin = ExtractPinFromReading(tmp.Substring(_prefijo.Length, tmp.Length - _prefijo.Length - _sufijo.Length).Trim());
if (pin != string.Empty)
handlerData(this, new DataEventArgs() { SourceName = "KBD", Data = pin });
else
return IntPtr.Zero;
}
}
}
else if (charPressed != 0x1B)
return IntPtr.Zero;
}
}
else if ((wParam == (IntPtr)KbdNativeMethods.WM_SYSKEYUP) || (wParam == (IntPtr)KbdNativeMethods.WM_KEYUP))
{
if (kbd.vkCode == (uint)KbdNativeMethods.VirtualKeyStates.VK_LSHIFT || kbd.vkCode == (uint)KbdNativeMethods.VirtualKeyStates.VK_RSHIFT)
_shiftPressed = false;
else if (kbd.vkCode == (uint)KbdNativeMethods.VirtualKeyStates.VK_CAPITAL)
_capsLockOn = false;
}
else
return IntPtr.Zero;
}
}
return KbdNativeMethods.CallNextHookEx(_keyBoardHandle, nCode, wParam, lParam);
}
As you can see, I am trying to filter those weird bytes out by returning IntPtr.Zero from the handler, but it did not work.
Any help please?
if (!Main.isAttached)
{
num++;
if (num <= 15)
{
try
{
Main.gameProcess = Process.GetProcessesByName("csgo")[0];
if ((Main.gameProcess == null || !Main.IsModuleLoaded(Main.gameProcess, "client_panorama.dll") ? true : !Main.IsModuleLoaded(Main.gameProcess, "engine.dll")))
{
continue;
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
continue;
}
while (true)
{
if ((Main.clientPanoramaDll == null ? false : Main.engineDll != null))
{
break;
}
Thread.Sleep(100);
Main.clientPanoramaDll = Main.GetModuleHandle(Main.gameProcess, "client_panorama.dll");
Main.engineDll = Main.GetModuleHandle(Main.gameProcess, "engine.dll");
}
Main.isAttached = true;
}
else
{
MessageBox.Show("CSGO Not Open!", "Open the game first.", MessageBoxButtons.OK, MessageBoxIcon.Hand);
base.Close();
break;
}
}
I am trying to program a mod for CSGO but it says it cannot detect the game is opened when it is already opened! I tried changing It to csgo.exe, csgo.exe32, but nothing works. Any tips please?
You didn't share with us your IsModuleLoaded() function so we can't answer this question, but here is the code I use which should solve your problem:
public static IntPtr GetModuleBaseAddress(Process proc, string modName)
{
IntPtr addr = IntPtr.Zero;
foreach (ProcessModule m in proc.Modules)
{
if (m.ModuleName == modName)
{
addr = m.BaseAddress;
break;
}
}
return addr;
}
Process proc = Process.GetProcessesByName("csgo")[0];
var modBase = ghapi.GetModuleBaseAddress(proc, "client.dll");
You can check the return value of GetModuleBaseAddress, if it's equal to IntPtr.Zero then the module was not loaded. It also will serve as the module handle, so you don't need additional redundant code.
all
i used FFmpeg.AutoGen 3.2 ,vs2015 in win7,copy a Example from FFmpeg(http://ffmpeg.org/doxygen/trunk/filtering_video_8c-example.html),
when run
string video = #"e:\\1.avi";
FilterVideo fv = new FilterVideo();
fv.filtertest(video);
return errorcode -22:
args:video_size=640x480:pix_fmt=AV_PIX_FMT_YUV420P:time_base=1/25:pixel_aspect=1/1
Cannot create buffer source
-22
thanks for any rep.
blow is code :
using FFmpeg.AutoGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace videoFFmpegAutoGen.tool
{
public unsafe class FilterVideo
{
public int open_input_file(string filename)
{
try
{
int ret;
AVCodec* dec;
fixed (AVFormatContext** at = &fmt_ctx)
{
ret = ffmpeg.avformat_open_input(at, filename, null, null);
}
if (ret < 0)
{
Console.WriteLine("Cannot open input file\n");
return ret;
}
ret = ffmpeg.avformat_find_stream_info(fmt_ctx, null);
if (ret < 0)
{
Console.WriteLine("Cannot find stream information\n");
return ret;
}
ret = ffmpeg.av_find_best_stream(fmt_ctx, AVMediaType.AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);
if (ret < 0)
{
Console.WriteLine("Cannot find a video stream in the input file\n");
return ret;
}
video_stream_index = ret;
/* create decoding context */
dec_ctx = ffmpeg.avcodec_alloc_context3(dec);
ffmpeg.avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
ffmpeg.av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
/* init the video decoder */
if ((ret = ffmpeg.avcodec_open2(dec_ctx, dec, null)) < 0)
{
Console.WriteLine("Cannot open video decoder\n");
return ret;
}
return ret;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
}
return -1;
}
private string filters_descr = "scale=78:24,transpose=cclock";
private int video_stream_index = -1;
private AVFormatContext* fmt_ctx;
private AVFilterGraph* filter_graph;
AVFilterContext* buffersrc_ctx;
private AVCodecContext* dec_ctx;
AVFilterContext* buffersink_ctx;
public unsafe int init_filters(string filters_descr)
{
int ret = 0;
AVFilterInOut* outputs = null;
AVFilterInOut* inputs = null;
try
{
AVFilter* buffersrc = ffmpeg.avfilter_get_by_name("buffer");
AVFilter* buffersink = ffmpeg.avfilter_get_by_name("buffersink");
outputs = ffmpeg.avfilter_inout_alloc();
inputs = ffmpeg.avfilter_inout_alloc();
AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
filter_graph = ffmpeg.avfilter_graph_alloc();
//string args = string.Format("video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, time_base.num, time_base.den, dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
string args = string.Format("video_size={0}x{1}:pix_fmt={2}:time_base={3}/{4}:pixel_aspect={5}/{6}", dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, time_base.num, time_base.den, dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
// string args = string.Format("video_size={0}x{1}:time_base={2}/{3}:pixel_aspect={4}/{5}", dec_ctx->width, dec_ctx->height, time_base.num, time_base.den, dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
// string args = string.Format("video_size={0}x{1}", dec_ctx->width, dec_ctx->height);
Console.WriteLine("args:" + args);
fixed (AVFilterContext** at= &buffersrc_ctx)
{
ret = ffmpeg.avfilter_graph_create_filter(at, buffersrc, "in", args, null, filter_graph);
}
if (ret < 0)
{
Console.WriteLine("Cannot create buffer source\n"+ret);
return ret;
}
fixed (AVFilterContext** at = &buffersink_ctx)
{
ret = ffmpeg.avfilter_graph_create_filter(at, buffersink, "out", null, null, filter_graph);
}
if (ret < 0)
{
Console.WriteLine("Cannot create buffer sink\n");
return ret;
}
// ret = ffmpeg.av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
/*
* The buffer source output must be connected to the input pad of
* the first filter described by filters_descr; since the first
* filter input label is not specified, it is set to "in" by
* default.
*/
outputs->name = ffmpeg.av_strdup("in");
outputs->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
outputs->next = null;
/*
* The buffer sink input must be connected to the output pad of
* the last filter described by filters_descr; since the last
* filter output label is not specified, it is set to "out" by
* default.
*/
inputs->name = ffmpeg.av_strdup("out");
inputs->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = null;
ret = ffmpeg.avfilter_graph_parse_ptr(filter_graph, filters_descr, &inputs, &outputs, null);
if (ret < 0)
{
return ret;
}
ret = ffmpeg.avfilter_graph_config(filter_graph, null);
if (ret < 0)
{
return ret;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
ffmpeg.avfilter_inout_free(&inputs);
ffmpeg.avfilter_inout_free(&outputs);
}
return ret;
}
long AV_NOPTS_VALUE = 1;
//int last_pts = AV_NOPTS_VALUE;
long last_pts = 1;
public void display_frame(AVFrame* frame, AVRational time_base)
{
int x, y;
long delay;
sbyte* p0;
sbyte* p;
AVRational cq = new AVRational();
cq.num = 1;
cq.den = 1000000;
if (frame->pts != AV_NOPTS_VALUE)
{
if (last_pts != AV_NOPTS_VALUE)
{
/* sleep roughly the right amount of time;
* usleep is in microseconds, just like AV_TIME_BASE. */
delay = ffmpeg.av_rescale_q(frame->pts - last_pts, time_base, cq);
if (delay > 0 && delay < 1000000)
Thread.Sleep((int)delay);
}
last_pts = frame->pts;
}
/* Trivial ASCII grayscale display. */
p0 = frame->data0;
//puts("\033c");
for (y = 0; y < frame->height; y++)
{
p = p0;
//for (x = 0; x < frame->width; x++)
//putchar(" .-+#"[*(p++) / 52]);
//putchar('\n');
p0 += frame->linesize[0];
}
//fflush(stdout);
}
private int AV_BUFFERSRC_FLAG_KEEP_REF = 8 ;
public unsafe void filtertest(string inputvideo)
{
AVFrame* frame = ffmpeg.av_frame_alloc();
AVFrame* filt_frame = ffmpeg.av_frame_alloc();
try
{
int ret;
AVPacket packet;
ffmpeg.av_register_all();
ffmpeg.avfilter_register_all();
ret = open_input_file(inputvideo);
if (ret < 0)
{
return;
}
ret = init_filters(filters_descr);
if (ret < 0)
{
return;
}
while (true)
{
ret = ffmpeg.av_read_frame(fmt_ctx, &packet);
if (ret < 0)
{
Console.WriteLine("Error while sending a packet to the decoder\n");
break;
}
if (packet.stream_index == video_stream_index)
{
ret = ffmpeg.avcodec_send_packet(dec_ctx, &packet);
if (ret < 0)
{
Console.WriteLine( "Error while sending a packet to the decoder\n");
break;
}
while (ret >= 0)
{
ret = ffmpeg.avcodec_receive_frame(dec_ctx, frame);
//if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
if (ret == 999)
{
break;
}
else if (ret < 0)
{
Console.WriteLine("Error while receiving a frame from the decoder\n");
return;
} else
{
Console.WriteLine("ret::"+ret);
}
if (ret >= 0)
{
frame->pts = frame->best_effort_timestamp;
/* push the decoded frame into the filtergraph */
if (ffmpeg.av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0)
{
Console.WriteLine("Error while feeding the filtergraph\n");
break;
}
/* pull filtered frames from the filtergraph */
while (true)
{
ret = ffmpeg.av_buffersink_get_frame(buffersink_ctx, filt_frame);
//if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
if (ret == 999)
{
break;
}
else if (ret < 0)
{
return;
}else
{
Console.WriteLine("ret2:" + ret);
}
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
ffmpeg.av_frame_unref(filt_frame);
}
ffmpeg.av_frame_unref(frame);
}
}
}
ffmpeg.av_packet_unref(&packet);
}
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
fixed (AVFilterGraph** at = &filter_graph)
{
ffmpeg.avfilter_graph_free(at);
}
ffmpeg.avcodec_close(dec_ctx);
fixed (AVFormatContext** at = &fmt_ctx)
{
ffmpeg.avformat_close_input(at);
}
ffmpeg.av_frame_free(&frame);
ffmpeg.av_frame_free(&filt_frame);
}
}
}
}
I would bet the problem is in this line:
string args = string.Format("video_size={0}x{1}:pix_fmt={2}:time_base={3}/{4}:pixel_aspect={5}/{6}", dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, time_base.num, time_base.den, dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
The pix_fmt is most certainly an int instead of being passed as a string.
So get the integer value of dec_ctx->pix_fmt and it should work.
I have Xamarin iOS app with in-app products. I get base64 encoded app receipt:
NSUrl receiptURL = NSBundle.MainBundle.AppStoreReceiptUrl;
String receiptData = receipt.GetBase64EncodedString(0);
According to Apple docs 7.0+ app receipt is packed in PKCS7 container using ASN1. When I send it to apple server it returns receipt in JSON. But I want to parse it locally to know what iaps user does already have. I don't need validation, as Apple does it remotely, I just need to get receipts for purchased inaps.
So far, as an investigation, I've parsed it in php with phpseclib, manually (no idea how to do this programatically) located receipt and parsed it as well.
$asn_parser = new File_ASN1();
//parse the receipt binary string
$pkcs7 = $asn_parser->decodeBER(base64_decode($f));
//print_r($pkcs7);
$payload_sequence = $pkcs7[0]['content'][1]['content'][0]['content'][2]['content'];
$pld = $asn_parser->decodeBER($payload_sequence[1]['content'][0]['content']);
//print_r($pld);
$prd = $asn_parser->decodeBER($pld[0]['content'][21]['content'][2]['content']);
print_r($prd);
But even this way I've got a mess of attributes, each looks like:
Array
(
[start] => 271
[headerlength] => 2
[type] => 4
[content] => 2016-08-22T13:22:00Z
[length] => 24
)
It is not human readable, I need something like (output with print_r of returned by Apple) :
[receipt] => Array
(
[receipt_type] => ProductionSandbox
[adam_id] => 0
[app_item_id] => 0
[bundle_id] => com.my.test.app.iOS
...
[in_app] => Array
(
[0] => Array
(
[quantity] => 1
[product_id] => test_iap_1
[transaction_id] => 1000000230806171
...
[is_trial_period] => false
)
)
)
Things seem too complicated, I hardly believe unpacking receipt is so complex. Does anybody know how to manage this? I've found this post but library is written in objective-C which is not applicable to my current environment. I'd say sources of this lib are frightened me: so much complex code just to unpack standartized container. I mean working with json, bson, etc. is very easy, but not asn1.
Finally I've unpacked it using Liping Dai LCLib (lipingshare.com). Asn1Parser returns DOM-like tree with root node - very handy lib.
public class AppleAppReceipt
{
public class AppleInAppPurchaseReceipt
{
public int Quantity;
public string ProductIdentifier;
public string TransactionIdentifier;
public DateTime PurchaseDate;
public string OriginalTransactionIdentifier;
public DateTime OriginalPurchaseDate;
public DateTime SubscriptionExpirationDate;
public DateTime CancellationDate;
public int WebOrderLineItemID;
}
const int AppReceiptASN1TypeBundleIdentifier = 2;
const int AppReceiptASN1TypeAppVersion = 3;
const int AppReceiptASN1TypeOpaqueValue = 4;
const int AppReceiptASN1TypeHash = 5;
const int AppReceiptASN1TypeReceiptCreationDate = 12;
const int AppReceiptASN1TypeInAppPurchaseReceipt = 17;
const int AppReceiptASN1TypeOriginalAppVersion = 19;
const int AppReceiptASN1TypeReceiptExpirationDate = 21;
const int AppReceiptASN1TypeQuantity = 1701;
const int AppReceiptASN1TypeProductIdentifier = 1702;
const int AppReceiptASN1TypeTransactionIdentifier = 1703;
const int AppReceiptASN1TypePurchaseDate = 1704;
const int AppReceiptASN1TypeOriginalTransactionIdentifier = 1705;
const int AppReceiptASN1TypeOriginalPurchaseDate = 1706;
const int AppReceiptASN1TypeSubscriptionExpirationDate = 1708;
const int AppReceiptASN1TypeWebOrderLineItemID = 1711;
const int AppReceiptASN1TypeCancellationDate = 1712;
public string BundleIdentifier;
public string AppVersion;
public string OriginalAppVersion; //какую покупали
public DateTime ReceiptCreationDate;
public Dictionary<string, AppleInAppPurchaseReceipt> PurchaseReceipts;
public bool parseAsn1Data(byte[] val)
{
if (val == null)
return false;
Asn1Parser p = new Asn1Parser();
var stream = new MemoryStream(val);
try
{
p.LoadData(stream);
}
catch (Exception e)
{
return false;
}
Asn1Node root = p.RootNode;
if (root == null)
return false;
PurchaseReceipts = new Dictionary<string, AppleInAppPurchaseReceipt>();
parseNodeRecursive(root);
return !string.IsNullOrEmpty(BundleIdentifier);
}
private static string getStringFromSubNode(Asn1Node nn)
{
string dataStr = null;
if ((nn.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.OCTET_STRING && nn.ChildNodeCount > 0)
{
Asn1Node n = nn.GetChildNode(0);
switch (n.Tag & Asn1Tag.TAG_MASK)
{
case Asn1Tag.PRINTABLE_STRING:
case Asn1Tag.IA5_STRING:
case Asn1Tag.UNIVERSAL_STRING:
case Asn1Tag.VISIBLE_STRING:
case Asn1Tag.NUMERIC_STRING:
case Asn1Tag.UTC_TIME:
case Asn1Tag.UTF8_STRING:
case Asn1Tag.BMPSTRING:
case Asn1Tag.GENERAL_STRING:
case Asn1Tag.GENERALIZED_TIME:
{
if ((n.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.UTF8_STRING)
{
UTF8Encoding unicode = new UTF8Encoding();
dataStr = unicode.GetString(n.Data);
}
else
{
dataStr = Asn1Util.BytesToString(n.Data);
}
}
break;
}
}
return dataStr;
}
private static DateTime getDateTimeFromSubNode(Asn1Node nn)
{
string dataStr = getStringFromSubNode(nn);
if (string.IsNullOrEmpty(dataStr))
return DateTime.MinValue;
DateTime retval = DateTime.MaxValue;
try
{
retval = DateTime.Parse(dataStr);
}
catch (Exception e)
{
}
return retval;
}
private static int getIntegerFromSubNode(Asn1Node nn)
{
int retval = -1;
if ((nn.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.OCTET_STRING && nn.ChildNodeCount > 0)
{
Asn1Node n = nn.GetChildNode(0);
if ((n.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.INTEGER)
retval = (int)Asn1Util.BytesToLong(n.Data);
}
return retval;
}
private void parseNodeRecursive(Asn1Node tNode)
{
bool processed_node = false;
if ((tNode.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.SEQUENCE && tNode.ChildNodeCount == 3)
{
Asn1Node node1 = tNode.GetChildNode(0);
Asn1Node node2 = tNode.GetChildNode(1);
Asn1Node node3 = tNode.GetChildNode(2);
if ((node1.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.INTEGER && (node2.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.INTEGER &&
(node3.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.OCTET_STRING)
{
processed_node = true;
int type = (int)Asn1Util.BytesToLong(node1.Data);
switch (type)
{
case AppReceiptASN1TypeBundleIdentifier:
BundleIdentifier = getStringFromSubNode(node3);
break;
case AppReceiptASN1TypeAppVersion:
AppVersion = getStringFromSubNode(node3);
break;
case AppReceiptASN1TypeOpaqueValue:
break;
case AppReceiptASN1TypeHash:
break;
case AppReceiptASN1TypeOriginalAppVersion:
OriginalAppVersion = getStringFromSubNode(node3);
break;
case AppReceiptASN1TypeReceiptExpirationDate:
break;
case AppReceiptASN1TypeReceiptCreationDate:
ReceiptCreationDate = getDateTimeFromSubNode(node3);
break;
case AppReceiptASN1TypeInAppPurchaseReceipt:
{
if (node3.ChildNodeCount > 0)
{
Asn1Node node31 = node3.GetChildNode(0);
if ((node31.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.SET && node31.ChildNodeCount > 0)
{
AppleInAppPurchaseReceipt receipt = new AppleInAppPurchaseReceipt();
for (int i = 0; i < node31.ChildNodeCount; i++)
{
Asn1Node node311 = node31.GetChildNode(i);
if ((node311.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.SEQUENCE && node311.ChildNodeCount == 3)
{
Asn1Node node3111 = node311.GetChildNode(0);
Asn1Node node3112 = node311.GetChildNode(1);
Asn1Node node3113 = node311.GetChildNode(2);
if ((node3111.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.INTEGER && (node3112.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.INTEGER &&
(node3113.Tag & Asn1Tag.TAG_MASK) == Asn1Tag.OCTET_STRING)
{
int type1 = (int)Asn1Util.BytesToLong(node3111.Data);
switch (type1)
{
case AppReceiptASN1TypeQuantity:
receipt.Quantity = getIntegerFromSubNode(node3113);
break;
case AppReceiptASN1TypeProductIdentifier:
receipt.ProductIdentifier = getStringFromSubNode(node3113);
break;
case AppReceiptASN1TypeTransactionIdentifier:
receipt.TransactionIdentifier = getStringFromSubNode(node3113);
break;
case AppReceiptASN1TypePurchaseDate:
receipt.PurchaseDate = getDateTimeFromSubNode(node3113);
break;
case AppReceiptASN1TypeOriginalTransactionIdentifier:
receipt.OriginalTransactionIdentifier = getStringFromSubNode(node3113);
break;
case AppReceiptASN1TypeOriginalPurchaseDate:
receipt.OriginalPurchaseDate = getDateTimeFromSubNode(node3113);
break;
case AppReceiptASN1TypeSubscriptionExpirationDate:
receipt.SubscriptionExpirationDate = getDateTimeFromSubNode(node3113);
break;
case AppReceiptASN1TypeWebOrderLineItemID:
receipt.WebOrderLineItemID = getIntegerFromSubNode(node3113);
break;
case AppReceiptASN1TypeCancellationDate:
receipt.CancellationDate = getDateTimeFromSubNode(node3113);
break;
}
}
}
}
if (!string.IsNullOrEmpty(receipt.ProductIdentifier))
PurchaseReceipts.Add(receipt.ProductIdentifier, receipt);
}
}
}
break;
default:
processed_node = false;
break;
}
}
}
if (!processed_node)
{
for (int i = 0; i < tNode.ChildNodeCount; i++)
{
Asn1Node chld = tNode.GetChildNode(i);
if (chld != null)
parseNodeRecursive(chld);
}
}
}
}
And usage:
public void printAppReceipt()
{
NSUrl receiptURL = NSBundle.MainBundle.AppStoreReceiptUrl;
if (receiptURL != null)
{
Console.WriteLine("receiptUrl='" + receiptURL + "'");
NSData receipt = NSData.FromUrl(receiptURL);
if (receipt != null)
{
byte[] rbytes = receipt.ToArray();
AppleAppReceipt apprec = new AppleAppReceipt();
if (apprec.parseAsn1Data(rbytes))
{
Console.WriteLine("Received receipt for " + apprec.BundleIdentifier + " with " + apprec.PurchaseReceipts.Count +
" products");
Console.WriteLine(JsonConvert.SerializeObject(apprec,Formatting.Indented));
}
}
else
Console.WriteLine("receipt == null");
}
}
I have a method that sends a message to a client as seen below. But if I call this method twice once after another it won't work properly and the data seems to have never been sent at all.
I added some comments below to show the issue.
public static void SendRequestInformation(Client target, int messageId)
{
NetworkStream stream = target.getClientSocket().GetStream();
byte[] byteData = null;
switch (messageId)
{
case 0:
byteData = Encoding.ASCII.GetBytes("ping");
break;
case 1:
byteData = Encoding.ASCII.GetBytes("handshake");
break;
case 3:
byteData = Encoding.ASCII.GetBytes("osif");
break;
case 4:
byteData = Encoding.ASCII.GetBytes("idle");
break;
}
try
{
stream.Write(byteData, 0, byteData.Length);
stream.Flush();
}
catch (Exception e)
{
ClientHandle.RemoveFromClientPool(target, "Unable to reach Client");
}
}
// so if here I have a method like...
private void onRefreshMenuClick(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi != null)
{
ContextMenu cm = mi.CommandParameter as ContextMenu;
if (cm != null)
{
Grid g = cm.PlacementTarget as Grid;
if (g != null)
{
var p = Mouse.GetPosition(g);
int row = 0;
int col = 0;
double accumulatedHeight = 0.0;
double accumulatedWidth = 0.0;
// calc row mouse was over
foreach (var rowDefinition in g.RowDefinitions)
{
accumulatedHeight += rowDefinition.ActualHeight;
if (accumulatedHeight >= p.Y)
break;
row++;
}
Client c = getRowClient(row);
if (c != null)
{
//the below two lines seem to not be called if called only the top one seems to work
ConnectionHandle.SendRequestInformation(c, 1);
ConnectionHandle.SendRequestInformation(c, 4);
}
else
if (debugWindow != null)
debugWindow.LogTextBox.AppendText("Unable to find client!");
}
}
}
}