Does anyone has already successfully added Rochet2's Reforging script on AC ?
Mine works but not completely.
On character login the script should re-apply bonuses on reforged (& equipped) items, but it seems "player->GetItemByGuid()" can't find the requested item, so it's returning nothing.
TrinityCore code (works) :
uint32 lowGUID = (*result)[0].GetUInt32();
Item* invItem = player->GetItemByGuid(ObjectGuid(HighGuid::Item, 0, lowGUID));
if (invItem)
player->_ApplyItemMods(invItem, invItem->GetSlot(), false);
ReforgeData& data = player->reforgeMap[lowGUID];
data.increase = (*result)[1].GetUInt32();
data.decrease = (*result)[2].GetUInt32();
data.stat_value = (*result)[3].GetInt32();
if (invItem)
player->_ApplyItemMods(invItem, invItem->GetSlot(), true);
AzerothCore code (works, but "if (invItem)" condition never satisfied.
uint32 lowGUID = (*result)[0].GetUInt32();
Item* invItem = player->GetItemByGuid((uint64) MAKE_NEW_GUID(HIGHGUID_ITEM, 0, lowGUID));
if (invItem /*&& invItem->IsEquipped()*/)
player->_ApplyItemMods(invItem, invItem->GetSlot(), false);
ReforgeData& data = player->reforgeMap[lowGUID];
data.increase = (*result)[1].GetUInt32();
data.decrease = (*result)[2].GetUInt32();
data.stat_value = (*result)[3].GetInt32();
if (invItem /*&& invItem->IsEquipped()*/)
player->_ApplyItemMods(invItem, invItem->GetSlot(), true);
MAKE_NEW_GUID() returns something that looks like a guid.
But I don't know why "player->GetItemByGuid()" can't find the item.
The order of arguments to MAKE_NEW_GUID is different from ObjectGuid constructor. So since your arguments are in wrong order then the result is also wrong and item is not found. See the definition and use of MAKE_NEW_GUID for the correct order of arguments.
Related
Working with MS WebView2 in C++ I can see a number of "Sec-*"-headers if visiting https://manytools.org/http-html-text/http-request-headers/
Example of a few:
Sec-Fetch-Dest document
Sec-Fetch-User ?1
Sec-Fetch-Mode navigate
Sec-Fetch-Site none
Sec-Ch-Ua-Mobile ?0
Sec-Ch-Ua "Not A;Brand";v="99", "Chromium";v="100", "Microsoft Edge";v="100", "Microsoft Edge WebView2";v="100"
These new headers are mentioned in https://wicg.github.io/ua-client-hints/
Is there any way to access/edit those headers, preferably in C++?
It's possible to disable the Sec-Ch headers with a command line option:
--disable-features=UserAgentClientHint
and to do that from C++:
Microsoft::WRL::ComPtr<CoreWebView2EnvironmentOptions> options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
options->put_AdditionalBrowserArguments(L"--disable-features=UserAgentClientHint");
However, I want to be able to edit those values.
Further googling revealed this page which I guess answers this post:
https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
You are correct that the sec-* headers are part of the "forbidden header" lists. But they are forbidden for client code like the JS that runs on the user-agent. But user-agents like the browser can set those fields.
You can change some of the sec-* headers inside a callback added to add_WebResourceRequested. Some fields like Sec-Fetch-Site get overwritten afterwards, others like Sec-Fetch-Mode can be set, but can't be deleted because they will get a default value, if not set after the WebResourceRequestedEvent. But you can change most of the sec-ch ones like this:
NOTE: this code is only to demonstrate the approach, it's missing a bunch of error handling
EventRegistrationToken webResourceRequestedToken;
webviewWindow->AddWebResourceRequestedFilter(L"*", COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL);
webviewWindow->add_WebResourceRequested(
Callback<ICoreWebView2WebResourceRequestedEventHandler>([](ICoreWebView2* sender,
ICoreWebView2WebResourceRequestedEventArgs* args) {
COREWEBVIEW2_WEB_RESOURCE_CONTEXT resourceContext;
args->get_ResourceContext(&resourceContext);
ICoreWebView2WebResourceRequest* req = nullptr;
ICoreWebView2HttpRequestHeaders* headers = nullptr;
ICoreWebView2HttpHeadersCollectionIterator* iter = nullptr;
args->get_Request(&req);
req->get_Headers(&headers);
headers->GetIterator(&iter);
BOOL hasCurrent = FALSE;
iter->get_HasCurrentHeader(&hasCurrent);
std::vector<std::wstring> headersToDelete;
std::wstring secChPrefix = L"sec-ch";
while (hasCurrent) {
LPWSTR name = nullptr, value = nullptr;
iter->GetCurrentHeader(&name, &value);
if (secChPrefix.compare(0, secChPrefix.size(), name, secChPrefix.size()) == 0) {
headersToDelete.push_back(name);
}
iter->MoveNext(&hasCurrent);
}
for (auto header : headersToDelete) {
headers->RemoveHeader(header.c_str());
}
// Setting "Sec-Fetch-Site" will have no effect, will get overwritten afterwards
headers->SetHeader(L"Sec-Fetch-Site", L"same-origin");
// This will work, but removing this key will just make it take the default value
headers->SetHeader(L"Sec-Fetch-Mode", L"same-origin");
return S_OK;
}).Get(),
&webResourceRequestedToken);
I'm using TaskDialogIndirect to display prompts to the user. Normally this works just fine, but sometimes, after the program has been running for a while, it begins returning an error code that the MSDN entry does not list as being one of the error codes this function can return.
0x80040001 OLE_E_ADVF "Invalid advise flags"
I have checked all the inputs to the function against previous successful calls in the same run. Aside from differences in the string to be displayed, they are identical. (the strings are even the same length.)
// create task dialog struct
TASKDIALOGCONFIG tdc;
ZeroMemory(&tdc, sizeof(TASKDIALOGCONFIG));
tdc.cbSize = sizeof(tdc);
tdc.dwFlags = (((dwMessageBoxFlags & MB_OKCANCEL) == MB_OKCANCEL) ? TDF_ALLOW_DIALOG_CANCELLATION : 0) | TDF_POSITION_RELATIVE_TO_WINDOW;
tdc.hwndParent = hwndOwner;
tdc.hInstance = LGetHInstance();
tdc.pszContent = usrText.wsz;
tdc.pButtons = _pButtons;
tdc.cButtons = nButtons;
tdc.pszMainIcon = pszTaskDialogIcon;
tdc.pszWindowTitle = usrCaption.wsz;
tdc.nDefaultButton = nDefaultButton;
// display it now
int iButton = 0;
BOOL b = 0;
HRESULT hResult = TaskDialogIndirect(&tdc, &iButton, NULL, &b);
NEW INFORMATION
At the same time that TaskDialogIndirect stops behaving correctly, ShellExecute also stops working, as does CreateFile.
This was actually caused by an event handle leak elsewhere. When the available handles ran out, no more API calls which needed to create a handle could succeed. They did return a rather odd set of error codes though, none of which was "out of handles".
When I have an array of Sitecore IDs, for example TargetIDs from a MultilistField, how can I query the ContentSearchManager to return all the SearchResultItem objects?
I have tried the following which gives an "Only constant arguments is supported." error.
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(x => f.TargetIDs.Contains(x.ItemId));
rpt.DataBind();
}
I suppose I could build up the Linq query manually with multiple OR queries. Is there a way I can use Sitecore.ContentSearch.Utilities.LinqHelper to build the query for me?
Assuming I got this technique to work, is it worth using it for only, say, 10 items? I'm just starting my first Sitecore 7 project and I have it in mind that I want to use the index as much as possible.
Finally, does the Page Editor support editing fields somehow with a SearchResultItem as the source?
Update 1
I wrote this function which utilises the predicate builder as dunston suggests. I don't know yet if this is actually worth using (instead of Items).
public static List<T> GetSearchResultItemsByIDs<T>(ID[] ids, bool mustHaveUrl = true)
where T : Sitecore.ContentSearch.SearchTypes.SearchResultItem, new()
{
Assert.IsNotNull(ids, "ids");
if (!ids.Any())
{
return new List<T>();
}
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var predicate = PredicateBuilder.True<T>();
predicate = ids.Aggregate(predicate, (current, id) => current.Or(p => p.ItemId == id));
var results = s.GetQueryable<T>().Where(predicate).ToDictionary(x => x.ItemId);
var query = from id in ids
let item = results.ContainsKey(id) ? results[id] : null
where item != null && (!mustHaveUrl || item.Url != null)
select item;
return query.ToList();
}
}
It forces the results to be in the same order as supplied in the IDs array, which in my case is important. (If anybody knows a better way of doing this, would love to know).
It also, by default, ensures that the Item has a URL.
My main code then becomes:
var f = (Sitecore.Data.Fields.MultilistField) rootItem.Fields["Main navigation links"];
rpt.DataSource = ContentSearchHelper.GetSearchResultItemsByIDs<SearchResultItem>(f.TargetIDs);
rpt.DataBind();
I'm still curious how the Page Editor copes with SearchResultItem or POCOs in general (my second question), am going to continue researching that now.
Thanks for reading,
Steve
You need to use the predicate builder to create multiple OR queries, or AND queries.
The code below should work.
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var predicate = PredicateBuilder.True<SearchResultItem>();
foreach (var targetId in f.Targetids)
{
var tempTargetId = targetId;
predicate = predicate.Or(x => x.ItemId == tempTargetId)
}
rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(predicate);
rpt.DataBind();
}
I'm generating a reporting services report from an ASP.NET (MVC) based application but am having problems setting the parameters for the report.
I believe the issue has only occurred since we upgraded SQL Server from 2005 to 2008 R2 (and Reporting Services along with it).
The original error encountered was from calling rsExec.Render:
Procedure or function 'pCommunication_ReturnRegistrationLetterDetails'
expects parameter '#guid', which was not supplied.
Debugging the code I noticed that rsExec.SetExecutionParameters is returning the following response:
Cannot call 'NameOfApp.SQLRSExec.ReportExecutionService.SetExecutionParameters(NameOfApp.SQLRSExec.ParameterValue[],
string)' because it is a web method.
Here is the function in it's entirety:
public static bool ProduceReportToFile(string reportname, string filename, string[,] reportparams,
string fileformat)
{
bool successful = false;
SQLRS.ReportingService2005 rs = new SQLRS.ReportingService2005();
SQLRSExec.ReportExecutionService rsExec = new NameOfApp.SQLRSExec.ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rsExec.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Prepare Render arguments
string historyID = null;
string deviceInfo = null;
// Prepare format - available options are "PDF","Word","CSV","TIFF","XML","EXCEL"
string format = fileformat;
Byte[] results;
string encoding = String.Empty;
string mimeType = String.Empty;
string extension = String.Empty;
SQLRSExec.Warning[] warnings = null;
string[] streamIDs = null;
// Define variables needed for GetParameters() method
// Get the report name
string _reportName = reportname;
string _historyID = null;
bool _forRendering = false;
SQLRS.ParameterValue[] _values = null;
SQLRS.DataSourceCredentials[] _credentials = null;
SQLRS.ReportParameter[] _parameters = null;
// Get if any parameters needed.
_parameters = rs.GetReportParameters(_reportName, _historyID,
_forRendering, _values, _credentials);
// Load the selected report.
SQLRSExec.ExecutionInfo ei =
rsExec.LoadReport(_reportName, historyID);
// Prepare report parameter.
// Set the parameters for the report needed.
SQLRSExec.ParameterValue[] parameters =
new SQLRSExec.ParameterValue[1];
// Place to include the parameter.
if (_parameters.Length > 0)
{
for (int i = 0; i < _parameters.Length; i++)
{
parameters[i] = new SQLRSExec.ParameterValue();
parameters[i].Label = reportparams[i,0];
parameters[i].Name = reportparams[i, 0];
parameters[i].Value = reportparams[i, 1];
}
}
rsExec.SetExecutionParameters(parameters, "en-us");
results = rsExec.Render(format, deviceInfo,
out extension, out encoding,
out mimeType, out warnings, out streamIDs);
// Create a file stream and write the report to it
using (FileStream stream = System.IO.File.OpenWrite(filename))
{
stream.Write(results, 0, results.Length);
}
successful = true;
return successful;
}
Any ideas why I'm now unable to set parameters? The report generation works without issue if parameters aren't required.
Looks like it may have been an issue with how reporting services passes parameters through to the stored procedure providing the data. A string guid was being passed through to the report and the stored procedure expected a varchar guid. I suspect reporting services may have been noticing the string followed the guid format pattern and so passed it through as a uniqueidentifier to the stored procedure.
I changed the data source for the report from "stored procedure" to "text" and set the SQL as "EXEC pMyStoredOProcName #guid".
Please note the guid being passed in as a string to the stored procedure is probably not best practice... I was simply debugging an issue with another developers code.
Parameter _reportName cannot be null or empty. The [CLASSNAME].[METHODNAME]() reflection API could not create and return the SrsReportNameAttribute object
In this specific case it looks like an earlier full compile did not finish.
If you encounter this problem I would suggest that you first compile the class mentioned in the error message and see if this solves the problem.
go to AOT (get Ctrl+D)
in classes find CLASSNAME
3.compile it (F7)
I need to get the primary key for a row and then insert it into one of the other columns in a string.
So I've tried to do it something like this:
newsObj = new news();
newsObj.name = "test"
newsObj.Save();
newsObj.url = String.Format("blah.aspx?p={0}",newsObj.col_id);
newsObj.Save();
But it doesn't treat it as the same data object so newsObj.col_id always comes back as a zero. Is there another way of doing this? I tried this on another page and to get it to work I had to set newsObj.SetIsLoaded(true);
This is the actual block of code:
page p;
if (pageId > 0)
p = new page(ps => ps.page_id == pageId);
else
p = new page();
if (publish)
p.page_published = 1;
if (User.IsInRole("administrator"))
p.page_approved = 1;
p.page_section = staticParent.page_section;
p.page_name = PageName.Text;
p.page_parent = parentPageId;
p.page_last_modified_date = DateTime.Now;
p.page_last_modified_by = (Guid)Membership.GetUser().ProviderUserKey;
p.Add();
string urlString = String.Empty;
if (parentPageId > 0)
{
urlString = Regex.Replace(staticParent.page_url, "(.aspx).*$", "$1"); // We just want the static page URL (blah.aspx)
p.page_url = String.Format("{0}?p={1}", urlString, p.page_id);
}
p.Save();
If I hover the p.Save(); I can see the correct values in the object but the DB is never updated and there is no exception.
Thanks!
I faced the same problem with that :
po oPo = new po();
oPo.name ="test";
oPo.save(); //till now it works.
oPo.name = "test2";
oPo.save(); //not really working, it's not saving the data since isLoaded is set to false
and the columns are not considered dirty.
it's a bug in the ActiveRecord.tt for version 3.0.0.3.
In the method public void Add(IDataProvider provider)
immediately after SetIsNew(false);
there should be : SetIsLoaded(true);
the reason why the save is not working the second time is because the object can't get dirty if it is not loaded. By adding the SetIsLoaded(true) in the ActiveRecord.tt, when you are going to do run custom tool, it's gonna regenerate the .cs perfectly.